我一直在阅读JavaScript中的undefined
,现在我不确定我的理解是否正确。有很多关于如何检查undefined
的讨论,但不知何故,我找不到任何提及对我来说似乎对理解undefined
实际工作原理至关重要的东西(undefined
主机对象的属性)。这就是这个问题的原因,我需要确认我理解的是正确的,如果我错了,我将不胜感激。
好的,首先,undefined
是主机对象(window
浏览器中)的属性,因此使用它是完全合法的:
window.undefined
此属性的值为类型 "undefined"
。这是与Object
、String
、Number
和Null
一起的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
,我们现在创建了一个隐式全局变量。这可能真的很糟糕。如果我们做了一个简单的比较,我们就会收到一个引用错误问题的警报。