为啥在检查 null 的长度时我没有收到错误 [重复]
Posted
技术标签:
【中文标题】为啥在检查 null 的长度时我没有收到错误 [重复]【英文标题】:Why I'm not getting an error when checking the length of null [duplicate]为什么在检查 null 的长度时我没有收到错误 [重复] 【发布时间】:2016-08-04 17:51:54 【问题描述】:我正在使用match
和length
属性检查字符串中的位数。这是我的函数http://codepen.io/PiotrBerebecki/pen/redMLE的codepen@
最初在返回 numberOfDigits.length
时,我收到一条错误消息 (Cannot read property 'length' of null
)。我通过将行更改为(numberOfDigits && numberOfDigits.length)
解决了这个问题。
这可行,但我想更好地理解为什么现在可以执行新语句。解释器现在执行 `numberOfDigits.length 吗?
另外,为什么我们在操作数反转时会得到相同的错误(numberOfDigits.length && numberOfDigits)
?
这是完整的 javascript 代码:
function checkLength(str)
let numberOfDigits = str.match(/\d/g);
return (numberOfDigits && numberOfDigits.length);
console.log( checkLength('T3xt w1th sOme numb3rs') );
console.log( checkLength('Text with some numbers') );
更新 1: 下面的答案解释说:
&&
表达式中操作数的顺序很重要。
JavaScript 优化了 &&
运算符,如果第一个操作数的计算结果为 null,则 JavaScript 不会检查第二个操作数,因为表达式只能计算为 null
/ false
。
【问题讨论】:
这是一个条件。第一个必须为真才能运行第二个。因为 numberOfDigits 为 null (false),所以 JS 引擎不会读取第二部分。 undefined 和 0(零)也可以表示为 false。 @RaulFernandez 而''
是假的。
所以,空字符串('')、零(0)、未定义、null和false在条件中会被表示为false
@RaulFernandez 你把假和假混为一谈。 Falsy
值为:undefined
、null
、0
、''
、false
、NaN
。检查某事物是否为falsy
的正确方法是使用Boolean(falsyValue) === false
。
我的错,不知道怎么称呼。
【参考方案1】:
JavaScript 尝试优化 &&
运算符:
numberOfDigits && numberOfDigits.length
如果numberOfDigits
是一个假值(并且null
是falsy),那么整个表达式将是falsy 并且不需要评估@987654325 @。
Falsy 值为:undefined
、null
、0
、''
、false
、NaN
。检查某事是否虚假的一种方法是使用Boolean(falsyValue) === false
(或更实用但不那么冗长的! falsyValue
)。
这是&&
运算符的副作用。我可以建议避免使用它并将代码转换为可读的内容:
function checkLength(str)
let numberOfDigits = str.match(/\d/g);
return Array.isArray(numberOfDigits) ? numberOfDigits.length : 0;
【讨论】:
实际上,“整个表达式”将是falsy,而不是false。准确地说,它将等于null
。
@HugoWood 好提示。谢谢:)
Boolean(falsyValue) === false
是一种相当冗长的写法!falsyValue
。
@user2357112 Boolean(value)
为 falsy 返回false
,为truthy 返回true
,这在学习方面更容易理解(而不是!!value
)
@DmitriPavlutin:对于新手来说可能更容易理解,但Boolean(falsyValue) === false
不应该被称为进行检查的“正确方法”。我们有太多人认为比较是与价值观不同的“词性”,并且会做if (flag === true) return true; else return false;
之类的事情。【参考方案2】:
“解释器现在执行 `numberOfDigits.length 吗?”
不,JavaScript 会短路逻辑表达式 - 一旦知道结果(即and
中的第一个操作数为假或or
中的第一个操作数为真),就不会在表达式中执行进一步的操作。
文档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators
另外,请注意:&&
和 ||
在 JavaScript 中不一定返回布尔值
【讨论】:
【参考方案3】:原因是当解释器看到两个用逻辑和 (&&) 连接的操作时,它会首先执行前者,并且只有当它被评估为真时才会执行后者。
这就是为什么因为它发现numberOfDigits
为null,在JS 中相当于false,它会停止执行并且永远不会在numberOfDigits.length
上崩溃。
反过来,当然会崩溃。
在逻辑或 (||) 上,解释器将在第一条语句为真之后停止评估。
【讨论】:
【参考方案4】:我相信原因是条件的顺序很重要。
首先评估 numberOfDigits 条件,因此如果为假,则不会评估其余条件,您不会收到错误。
在另一个顺序中,您会尝试读取 null 的“length”属性,从而产生错误。
【讨论】:
【参考方案5】:“与”逻辑如下执行。
true & true = true
false & anything = false`
如果第一个条件失败,则没有执行第二个条件的意义。
因此,如果numberOfDigits
为空或未定义,则不会执行numberOfDigits.length
,因此在以下情况下不会出错。
(numberOfDigits && numberOfDigits.length) => false
false && anything => false
同理,如果第一个条件不为空,则执行第二个条件。
(numberOfDigits && numberOfDigits.length) => true
true && true (must be) => true
注意:在 javascript 中,
null
和undefined
被解释为false
在条件语句中。
【讨论】:
以上是关于为啥在检查 null 的长度时我没有收到错误 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
为啥 MailKit SmtpClient.Send() 失败时我没有收到异常?
为啥我会收到此错误:未捕获的类型错误:无法读取 null 的属性 'classList'