【问题标题】:Null coalescing string and conditional string via logical OR-operator results in number通过逻辑 OR 运算符的空值合并字符串和条件字符串导致数字
【发布时间】:2020-07-27 11:50:01
【问题描述】:

通过OR 合并一个字符串(通过PRIORITIES[NUM_TO_PRIORITY[priorityNum]],其中priorityNum 是输入)和一个字符串(通过条件Object.values(PRIORITIES).includes(priorityNum) ? priorityNum : PRIORITIES.low)进行空值合并应该输出一个字符串但输出一个数字(与输入匹配)。为什么会这样?

这可能是一个 js 怪癖,但不确定为什么输出是一个数字,因为测试表明合并应该在 2 个字符串之间以输出一个字符串:

const PRIORITIES = {
    high: 'HIGH',
    low: 'LOW',
};
const NUM_TO_PRIORITY = {
    0: 'high',
    1: 'low',
};
const priorityNum = 0;
console.log(PRIORITIES[NUM_TO_PRIORITY[priorityNum]]); // "HIGH"
console.log(Object.values(PRIORITIES).includes(priorityNum)); // false
console.log("HIGH" || false) // "HIGH" <- Expected output

// Based on the above code, the following code should output "HIGH" yet outputs 0, why does this happen?
console.log(PRIORITIES[NUM_TO_PRIORITY[priorityNum]] || Object.values(PRIORITIES).includes(priorityNum) ? priorityNum : PRIORITIES.low);

【问题讨论】:

  • 请点击编辑,然后[&lt;&gt;]sn-p编辑并发布minimal reproducible example
  • 感谢您的建议,添加了一个 sn-p 以防它帮助其他人:)

标签: javascript javascript-objects null-coalescing logical-or


【解决方案1】:

正如另一个答案中提到的,这是由于运算符优先级。

valOne || valTwo ? priorityNum : PRIORITIES.low;

等同于:

(valOne || valTwo) ? priorityNum : PRIORITIES.low;

但你想要:

valOne || (valTwo ? priorityNum : PRIORITIES.low);

由于大多数没有记住 20 多个运算符的优先级,因此可以通过使用更多括号(如上所示)或更多变量来避免这些错误:

const PRIORITIES = {
    high: 'HIGH',
    low: 'LOW',
};
const NUM_TO_PRIORITY = {
    0: 'high',
    1: 'low',
};
const priorityNum = 0;

const priority = PRIORITIES[NUM_TO_PRIORITY[priorityNum]]
const otherVal = Object.values(PRIORITIES).includes(priorityNum) ? priorityNum : PRIORITIES.low

priority || otherVal; // "HIGH"

【讨论】:

  • for Since most don't have the precedence memorized for 20+ ... +1
  • 括号很有用,为avoid these problems by ... +1 :)
【解决方案2】:

||operator precedence 高于 ?,因此您的代码被评估为

(PRIORITIES[NUM_TO_PRIORITY[priorityNum]] || Object.values(PRIORITIES).includes(priorityNum))  ? priorityNum : PRIORITIES.low

const PRIORITIES = {
    high: 'HIGH',
    low: 'LOW',
};
const NUM_TO_PRIORITY = {
    0: 'high',
    1: 'low',
};
const priorityNum = 0;
console.log(PRIORITIES[NUM_TO_PRIORITY[priorityNum]]); // "HIGH"
console.log(Object.values(PRIORITIES).includes(priorityNum)); // false
// "HIGH" || false // "HIGH" <- Expected output

// Based on the above code, the following code should output "HIGH" yet outputs 0, why does this happen?
console.log(PRIORITIES[NUM_TO_PRIORITY[priorityNum]] || Object.values(PRIORITIES).includes(priorityNum) ? priorityNum : PRIORITIES.low);

【讨论】:

  • 同意|| 具有更高的优先级,但这不应该意味着它变成(PRIORITIES[NUM_TO_PRIORITY[priorityNum]] || Object.values(PRIORITIES).includes(priorityNum)) 解析为"HIGH" || false 应该输出"HIGH"
  • @surajs02 no 进一步解析为“HIGH”? priorityNum : PRIORITIES.low 最终解析为 0
  • 抱歉,没有看到添加的括号,?|| 之后解析是有道理的,谢谢,会接受答案:)
猜你喜欢
  • 1970-01-01
  • 2020-02-18
  • 2021-11-28
  • 2021-12-21
  • 1970-01-01
  • 2020-10-06
  • 1970-01-01
  • 2015-02-14
  • 2020-05-02
相关资源
最近更新 更多