在JavaScript中,undefined
可以被重新赋值,所以通常建议创建一个自执行的函数来确保undefined实际上是undefined。作为替代,null
和undefined
肯定是==
,但是否有其他值与null/undefined
大致相等?
(function(undefined){
window.f = function(obj){
if(obj===undefined || obj===null ){
alert('value is undefined or null');
}
}
})();
:
window.f = function(obj){
if(obj==null){
alert('value is undefined or null');
}
}
如果上面是100%安全的,为什么JavaScript社区/库不完全放弃undefined
,并使用更短的x == null
条件来检查null
/undefined
?
我从来没有见过有人实际上代表"未知值"与"未定义"vs null
?我从未见过这种情况,这就是我最初问这个问题的原因。这似乎是两个令人难以置信的混淆值,从未在其原始意图中使用过。标准化一切来做比较obj==null
将有利于大小和避免重分配的任何问题。一切都会继续工作
var obj={};
obj.nonExistantProperty==null // true
var x;
ix==null // true
function(obj){
obj==null // true
}
该规则的一个例外似乎是当将undefined
/null
转换为整数时。这是一个相当古老的场景,但绝对应该注意。
+(null)==0
而isNaN(+undefined)
考虑到NaN是JavaScript中唯一不等于它自身的值,你可以做一些非常疯狂的事情,比如:
+undefined == +undefined // false
+null == +null // true
使用null
作为松散相等==
drop来替换undefined
是安全的,前提是您不打算将值强制转换为整数。这是一个非常极端的情况。
语言规范第11.9.3节中的抽象相等算法定义了==
和!=
,并且它定义了
null == void 0
null == null
void 0 == null
其中void 0
只是表示undefined
的可靠方式(见下文),所以你的问题的答案是肯定的,null
等于未定义和它本身,而不是其他。
规范的相关部分为
1. If Type(x) is the same as Type(y), then If Type(x) is Undefined, return true. If Type(x) is Null, return true. ... 2. If x is null and y is undefined, return true. 3. If x is undefined and y is null, return true. ...
如果你担心undefined
的意思与它通常的意思不同,那就用void 0
代替。
null == void 0 // True
({}).x === void 0 // True
"undefined" === typeof void 0 // True
(function () {})() === void 0 // True
(undefined = 42,
undefined === void 0) // False
"undefined" === typeof undefined // False
"undefined" === typeof void 0 // True
来自语言规范:
11.4.2 void操作符生成UnaryExpression:voidUnaryExpression按如下方式求值:
- 设
expr
为UnaryExpression/的求值结果。- 呼叫
GetValue(expr)
.- <返回strong>定义。返回strong>
因此,无论全局变量undefined
是否被修改(或者undefined
是否被定义:),void
前缀运算符对其参数求值并返回特殊值undefined。
编辑:在回应评论时,
如果您正在处理区分两者的库代码,那么您需要处理差异。语言委员会标准化的一些新库确实忽略了这些差异:JSON.stringify([void 0]) === "[null]"
,但是有太多的代码对它们进行了微妙的区别对待,还有其他的差异:
+(null) === 0
isNaN(+undefined)
"" + null === "null"
"" + undefined === "undefined"
如果你正在编写生成文本或序列化/反序列化的任何类型的库,并且你想合并两者,那么你不能通过undefined
并期望它表现为null
——你需要显式地将输入规范化为其中一个。
因为JavaScript有这两个值。当其他语言可能只有nil
/null
时,JavaScript的undefined
是"未知值",而null
显然是一个已知值,不代表任何东西。
比较var x
(x
没有定义,因为没有赋值)和var y = null
(y
是null
)。它被设置成一个代表"没有"的句子。undefined
和null
在JavaScript中的核心基本用法非常深入,其他情况包括:
- 缺少(或
delete
'd)属性也会产生undefined
而不是null
(只有在分配了null
的情况下才会产生null
)。 - 未分配的功能参数为
undefined
。
undefined
从getElementById
因此,在Javascript中,使用undefined
而不是null
通常更正确,它们代表不同的东西。试图解决这个问题的库就是在对抗JavaScript。
幸福的编码。
就我个人而言,在几乎所有情况下,我都避免显式检查undefined
或null
。我认为,在大多数情况下——但不是所有情况——所有的假值应该是相等的,调用者有责任遵守所述的公共契约。
由于这种信念,我认为比较x == null
在试图保护太多而又太少的边缘,但在捕获null
或 undefined
的情况下,它是有效的,正如所指出的那样。-)
因为:
var myVar1;
var myVar2 = null;
if (myVar1 === null) alert('myVar1 is null');
if (myVar1 === undefined) alert('myVar1 is undefined');
if (myVar2 === null) alert('myVar2 is null');
if (myVar2 === undefined) alert('myVar2 is undefined');
任何设置为null的东西都不是未定义的——它被定义为null。
Reading Javascript: The Good parts,似乎只有null和undefined是等价的
JavaScript有两组相等操作符:===和!==,以及它们的邪恶双胞胎==和!=。好的按照你期望的方式工作。如果两个操作数类型相同且值相同,则===生成true,而!==生成false。邪恶的双胞胎做正确的事当操作数是相同的类型,但如果它们是不同的类型,它们会尝试强制值。他们这么做的规则都是复杂且难以记忆的。以下是一些有趣的例子:
'' == '0' // false
0 == '' // true
0 == '0' // true
false == 'false' // false
false == '0' // true
false == undefined // false
false == null // false
null == undefined // true
' trn ' == 0 // true
"JavaScript: The Good Parts by Douglas Crockford "。版权所有2008雅虎!公司,978-0-596-51774-8。"