【问题标题】:How can I make a boolean determine the order of the values of a JavaScript Object?如何使布尔值确定 JavaScript 对象的值的顺序?
【发布时间】:2019-11-29 21:15:03
【问题描述】:

对于格式错误的标题,我真的想不出更好的方式来描述我的意思。这是我当前的代码:

fromEn = true; // some boolean value

options = {
  from: fromEn ? "en" : "es",
  to: fromEn ? "es" : "en"
};

fromEn 为真时,我希望from"en",而当它为假时"es"to 应该是 from 的“相反值”,可以这么说。我觉得我当前的代码太多余了,虽然它有效,但我想要一个更优雅的解决方案。有没有更好的方法来实现我想要做的事情?

编辑:我认为三元组是最好的方法。 See Emissary's solution 对于我选择做的事情,请看我的答案较低以找到三种可能的解决方案。谢谢大家的帮助!

【问题讨论】:

  • 你可以做类似const args = ["es", "en"]; options = { from: args[0^fromEn], to: args[1^fromEn]}的事情,但如果这样更好?我会怀疑的。我敢打赌,从现在起 2 个月后,即使是你也会想知道这是/做什么。
  • ^ 不是逻辑运算符。相反,它是 bitwise XOR ^ 运算符。
  • 我觉得options = fromEn ? {from:'en',to:'es'} : {from:'es',to:'en'} 更习惯用语,虽然这真的取决于个人喜好。
  • @Emissary 对,或者const [from, to] = fromEn? ["en", "es"]: ["es", "en"]; options = { from, to }; 或@101arrows,如果你还在寻找那些你在看的时候不会再理解的肮脏黑客,下一次:@987654335 @。我喜欢玩这种 hack,但是这些不应该出现在生产代码中。
  • 不知道所有这些不同的变化除了学术练习和使用大致相同数量的字符来达到相同的结果之外获得了什么

标签: javascript


【解决方案1】:

经过一番研究,我有三种可能的解决方案。

第一个(我将使用的那个 - 感谢使者!)

options = fromEn ? {from:'en',to:'es'} : {from:'es',to:'en'}

第二个(我想出了一个Bergi建议-最初对0 |0使用按位或)

const langs = ["es", "en"];
const opts = {
  from: langs[+fromEn],
  to: langs[+!fromEn]
}

第三(使用按位异或 - 感谢 Thomas!)

const langs = ["es", "en"];
options = { from: langs[0^fromEn], to: langs[1^fromEn]};

2nd 和 3rd 相当不可读,所以为了可读性,#1 是我的首选。

【讨论】:

  • 我会使用langs[+fromEn] / langs[+!fromEn] 进行数字转换,而不是|0(通常专门用于整数转换)。但我猜两者都很好,而且比 XOR 更奇怪。
  • @Bergi 根据 StackOverflow 的一些其他答案(例如 stackoverflow.com/questions/7820683/… - 请参阅第一条评论),一元 + 运算符的速度要慢 97%,所以我选择了 | 0。跨度>
  • 我怀疑这是真的(至少,衡量转换本身,而不是数字的后续使用),但最重要的是它们做不同的事情,所以要提防过早的优化。
  • 正如所料,一旦你do the microbenchmarks properly,所有的测试用例have the same performance。 97% 的差异仅出现在非常旧的引擎版本中,显然无法像其他引擎那样优化。
  • @Bergi 我已经纠正了。差异基本上可以忽略不计,你是对的。由于+ 运算符更具可读性和通用性,因此它是更好的选择。
【解决方案2】:

您可以使用属性获取器。 fromto 的这种方式将动态变化,具体取决于 fromEn 标志的值 - 我已将其移至 options 对象中,将属于一起的事物保持在一起。

let options = {
  fromEn: true,
  get from() { return this.fromEn ? "en" : "es" },
  get to() { return this.fromEn ? "es" : "en" }
};

console.log("From " + options.from + " to " + options.to);

options.fromEn = false;

console.log("From " + options.from + " to " + options.to);

【讨论】:

  • 谢谢你的回答,彼得!我更多的是寻求一种避免双重三元组的方法,而不是动态更改options 的值,但我肯定会在未来使用它(从不知道js getter 如此容易制作)
【解决方案3】:

怎么样

fromEn = true;
let options = {}
options.from = fromEn ? "en" : "es", options.to = fromEn ? "es" : "en"
console.log(options)

手动将属性添加到对象,用逗号分隔。你也可以这样做

fromEn = true;
let options = fromEn ? {from:"en",to:"es"} : {from:"es",to:"en"}
console.log(options)

【讨论】:

  • 逗号分隔符真的很奇怪。为什么不只使用两个语句和分号?
  • @Bergi 逗号有什么问题?看起来很短。对我来说精确、微妙。还为您节省了一行
  • 我看不出这个答案有什么问题。逗号分隔在 JavaScript 中很常见...
  • @weegee 用分号替换逗号同样简短而精确,但不那么微妙。如果您不知道条件运算符和逗号运算符之间的优先级,那么逗号运算符也是不明确的。保存行是缩小器的工作,而不是开发人员的工作。第二个 sn-p 在所有方面要好得多。
  • @Bergi 我不明白最后一条评论,但如果要摆弄一个 javascript miniifer,例如 if(x){foo();return bar()}else{return 1} 会变成 return x?(foo(),bar()):1 字节保存。
【解决方案4】:

请使用constlet 声明变量,以免这些变量污染范围。

您的问题的答案,切换fromEn

const fromEn = true; // some boolean value

const options = {
  from: fromEn ? "en" : "es",
  to: !fromEn ? "en" : "es"
};

希望这会有所帮助。

【讨论】:

  • 感谢您的回答,欢迎来到 Stack Overflow!我很欣赏您的解决方案,但它实际上与我的相同:在两个值中使用三元组,两次评估 fromEn。一个感叹号使您的回答与我的问题不同。我一直在寻找一种更优雅的做事方式,而不是两个三元组。无论如何,感谢您对使用 constlet 的建议。
猜你喜欢
  • 1970-01-01
  • 2015-07-03
  • 2021-06-21
  • 2017-11-10
  • 2019-10-09
  • 2010-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多