JavaScript 在未定义和 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

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

解决方法

有几件事正在发生:

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

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

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

    2(a) 如果 IsUnresolvableReference(val) 为真,则返回“未定义”。

  2. && 运算符短路

    && 评估它的第一个操作数,如果该值是假的,¹ 将假值作为其结果,对第二个操作数不做任何处理。但是,如果第一个操作数的值为真,&& 会评估第二个操作数并将该值作为结果。

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

我的问题是如果一个变量没有定义,那是不是和“未定义”一样

不是在一般情况下,不是。 typeof 很特别。对不存在的标识符所做的任何其他事情都会引发错误。 (好吧,还有一件事:在松散模式下,如果您分配给一个不存在的标识符,它会创建一个全局标识符。这就是我所说的 The Horror of Implicit Globals,也是使用 {{ 3}},这是它一直应该出现的错误。)


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

,

问题在于你对 JavaScript 中 && 运算符的理解,

举例说明:expr1 && expr2

如果expr1可以转换为true,则返回expr2;否则,返回 expr1。

在你的第一种情况下:
typeof myObj !== "undefined" // 这是错误的,因为 typeof myObj 是未定义的 所以它返回 undefined。

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