JavaScript 验证未定义和 null 时不同的变量类型

JavaScript validates variable types different when they are undefined and null

我在测试中看到这道题,没有声明变量myObj,要求根据以下if语句选择正确答案。

function myFunction() {
  if(typeof myObj !== "undefined" && myObj !== null) {
    a = 1
  }
}

result: "undefined" 

创建了 运行 这些语句和测试输出的函数。

 function myFunction() {
   if(myObj !== null && typeof myObj !== "undefined") {
    a = 1
   }
 }

 result: Uncaught ReferenceError: myObj is not defined

我的问题是,如果一个变量没有被定义,是不是和“undefined”一样,如果我想测试一个“undefined”值,我可以只使用“null”来检查它是否是undefined通过(例如 myObj === null),那么为什么第一个函数 returns 未定义而第二个 returns myObj 未定义?

发生了几件事:

  1. 值检查不同于类型检查。

    如果您尝试读取不存在的标识符的值,则会出现错误。因此,如果 myObj 不存在(标识符从未声明或以其他方式创建),myObj === null 会导致错误。

    但是在不存在的标识符上使用 typeof 会导致 "undefined",而不会出现错误。所以当 myObj 不存在时 typeof myObj"undefined"。您可以在 the specification 中看到:

    2(a) If IsUnresolvableReference(val) is true, return "undefined".

  2. &&运算符短路.

    && 评估其第一个操作数,如果该值是假的,¹ 将假值作为其结果,不对第二个操作数执行任何操作。但是,如果第一个操作数的值为真,&& 计算第二个操作数并将该值作为结果。

由于这两件事,if(typeof myObj !== "undefined" && myObj !== null) { 可以正常工作,因为它首先执行 typeof myObj !== "undefined",并且当 myObj 不存在时该值为 false&& 操作的结果是 true 并且永远不会评估第二个操作数。但是 if(myObj !== null && typeof myObj !== "undefined") { 首先执行 myObj !== null,尝试使用不存在的标识符的值,这会导致错误。

my questions is if an variable is not defined, isn't that the same as "undefined"

一般情况下不会,不会。 typeof 很特别。您对不存在的标识符执行的任何其他操作都会引发错误。 (好吧,还有一件事:在松散模式下,如果你分配给一个不存在的标识符,它会创建一个全局的。这就是我所说的 The Horror of Implicit Globals and is one of the many reasons to use strict mode,它总是应该出现的错误。 )


¹ “truthy” 和 “falsy” 是我们在 JavaScript 中使用的术语,指的是当用作条件时强制为 true 的值和强制为 false 的值。有一组固定的假值:0""NaNnullundefined,当然还有 false(也document.all 在浏览器中;奇怪但真实)。所有其他值都是真实的。

问题在于您对 JavaScript、

中 && 运算符的理解

举例说明:expr1 && expr2

如果expr1可以转换为真,returnsexpr2;否则,returns expr1.

在你的第一个案例中:
typeof myObj !== "undefined" // 这是错误的,因为 typeof myObj 是未定义的 所以它 returns 未定义。

在你的第二种情况下: myObj !== "null" // 这给出了 Uncaught ReferenceError: myobj is not defined, 因为这是 不正确,返回同样的错误