理解Javascript中的“未定义”:它是如何工作的,如何安全地检查它以及是否可以重新分配

Understanding “undefined” in Javascript: how it works, how to safely check against it and whether reassignment is possible

本文关键字:未定义 分配 检查 是否 安全 新分配 何工作 Javascript 中的 理解 工作      更新时间:2023-09-26

我一直在阅读JavaScript中的undefined,现在我不确定我的理解是否正确。有很多关于如何检查undefined的讨论,但不知何故,我找不到任何提及对我来说似乎对理解undefined实际工作原理至关重要的东西(undefined主机对象的属性)。这就是这个问题的原因,我需要确认我理解的是正确的,如果我错了,我将不胜感激。

好的,首先,undefined是主机对象(window浏览器中)的属性,因此使用它是完全合法的:

window.undefined

此属性的值为类型 "undefined" 。这是与ObjectStringNumberNull一起的JavaScript类型之一。因此,如果我这样做:

if(someVar===undefined) {}

我实际上是在检查window.undefined财产,无论它包含什么,对吗?

所以下面的代码会很愚蠢,因为这只会检查someVar字符串"undefined",而不是window对象的类型和属性,对吧?

if(someVar==='undefined') {}

下面也是不正确的,因为这将检查window.undefined属性(无论它包含什么):

if(typeof someVar===undefined) {}

因此,总而言之,检查未定义的唯一正确和跨浏览器方法是使用typeof例如:

if(typeof someVar==='undefined')

是吗?

同样在 ES5 中window.undefined无法重新分配,但在旧浏览器中是完全合法的,对吗?

然而,如果我的理解是正确的,这仍然可以做到,并且是邪恶的:

(function() { 
  var undefined=66;
  alert(undefined);
})()

如果我误解了undefined在 JavaScript 中的工作方式,我将不胜感激。

你几乎是对的。除了这个:

[window.undefined] 的值类型为"undefined"。这是Javascriupt类型之一,以及对象,字符串,数字和空

javascript中有3个undefined。全局变量undefined、值undefined和类型undefined

即使全局变量 undefined 被覆盖,该值undefined仍然存在。有几种方法可以获取它,其中一种是函数的空参数,另一种是不分配任何内容的变量声明:

// Note: Probably need older browsers to assign to undefined:
window.undefined = 1;
(function(foo){ // the value of foo is undefined;
    var bar;    // the value of bar is undefined;
    return [foo === bar, foo === window.undefined]; // returns [true,false]
})();

请注意,在上面的示例中,我们检查的是值,而不是类型。是的,===检查类型和值,但如果将===替换为==则结果将是相同的。

undefined的类型为 undefined(规范和文档中为"未定义",但 typeof 返回"未定义"),并且类型 undefined 仅对值 undefined 有效。

这一切都很好,另外:

  • 您可以使用void 0可靠地"生成"真正的undefined值(或非值;这是一种禅宗)
  • 在函数中,您可以引用已知未提供的参数以获得可靠的undefined

    (function( undefined ) {
      // ...
    })();
    

    第二个示例并不是世界上最清晰的代码,但您有时会在常见的公共代码库、教程等中看到它。

因此,如果我这样做:

if(someVar===undefined) {}

我实际上正在检查窗口.未定义的属性,无论它是什么 包含对吗?

右。

所以下面的代码会很愚蠢,因为这会检查someVar 仅针对未定义的字符串,而不是类型或属性 窗口对象对吗?

if(someVar==='undefined') {}

右。

下面的这也不正确,因为这将检查 window.undefined属性(无论它包含什么):

if(typeof someVar===undefined) {}

右。

所以总结一下,唯一正确和跨浏览器的检查方法 未定义是使用类型,例如:

if(typeof someVar==='undefined')

是吗?

是的,尽管它容易出错,因为您可能会错误地键入该字符串并且没有错误(即使在严格模式下)来指示错误。

所以最好调用一些方法,特别是如果你已经在使用一些框架,例如在 AngularJS 中 - angular.isUndefined

同样在 ES5 窗口中,undefined 无法重新分配,但它在旧浏览器中完全合法,对吗?

右。

然而,这仍然可以做到,如果我的理解是邪恶的 右:

(function() { 
var undefined=66;
alert(undefined);
})()

我相信是的。

因此,总而言之,

检查未定义的唯一正确和跨浏览器的方法是使用typeof,例如:

if(typeof someVar==='undefined')

不,直接比较somevar === undefined很好。

可以覆盖或隐藏任意数量的全局变量会破坏代码。除了不允许使用不良代码之外,没有办法防止所有这些代码。

<小时 />

直接比较的好处(除了更短更干净)是它必须更自然和直观,而人们经常弄错其他语法。他们最终意外地使用了您给出的其他示例:

if (somevar === 'undefined')
if (typeof somevar === undefined)

这些都是非常常见的错误,比人们重新定义undefined要常见得多。

<小时 />

此外,您会看到如下所示的内容:

if (typeof somevar === 'undefiend')

这要微妙得多,当被一堆其他代码包围时很难发现。同样,这是一个常见的错误。

<小时 />

最糟糕的情况可能是当你看到这个时:

if (typeof somevar === 'undefined')
    somevar = "foobar";

这是怎么回事?好吧,如果没有声明somevar,我们现在创建了一个隐式全局变量。这可能真的很糟糕。如果我们做了一个简单的比较,我们就会收到一个引用错误问题的警报。