为啥在检查 null 的长度时我没有收到错误 [重复]

Posted

技术标签:

【中文标题】为啥在检查 null 的长度时我没有收到错误 [重复]【英文标题】:Why I'm not getting an error when checking the length of null [duplicate]为什么在检查 null 的长度时我没有收到错误 [重复] 【发布时间】:2016-08-04 17:51:54 【问题描述】:

我正在使用matchlength 属性检查字符串中的位数。这是我的函数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 值为:undefinednull0''falseNaN。检查某事物是否为falsy 的正确方法是使用Boolean(falsyValue) === false 我的错,不知道怎么称呼。 【参考方案1】:

JavaScript 尝试优化 && 运算符:

numberOfDigits && numberOfDigits.length

如果numberOfDigits 是一个假值(并且nullfalsy),那么整个表达式将是falsy 并且不需要评估@987654325 @。

Falsy 值为:undefinednull0''falseNaN。检查某事是否虚假的一种方法是使用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 中,nullundefined 被解释为 false 在条件语句中。

【讨论】:

以上是关于为啥在检查 null 的长度时我没有收到错误 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

为啥 MailKit SmtpClient.Send() 失败时我没有收到异常?

为啥我会收到此错误:未捕获的类型错误:无法读取 null 的属性 'classList'

为啥我会收到“未使用的参数(na.action = NULL)”错误?

为啥从标准输入读取用户输入时我的字符串不匹配?

为啥切换语言环境时我的会话没有加载?

为啥从亚马逊弹性负载均衡器后面发送重定向时收到 502 错误网关?