JavaScript未定义替换为null

JavaScript undefined replaced with null

本文关键字:null 替换 未定义 JavaScript      更新时间:2023-09-26

在JavaScript中,undefined可以被重新赋值,所以通常建议创建一个自执行的函数来确保undefined实际上是undefined。作为替代,nullundefined肯定是==,但是否有其他值与null/undefined大致相等?

<标题> TLDR h1> 本上你可以安全地替换这个:
(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)==0isNaN(+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按如下方式求值:

  1. exprUnaryExpression/的求值结果。
  2. 呼叫GetValue(expr) .
  3. <返回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 (ynull)。它被设置成一个代表"没有"的句子。undefinednull在JavaScript中的核心基本用法非常深入,其他情况包括:

  1. 缺少(或delete 'd)属性也会产生undefined而不是null(只有在分配了null的情况下才会产生null)。
  2. 未分配的功能参数为undefined
  3. undefinedgetElementById 等标准函数返回。看到评论。

因此,在Javascript中,使用undefined而不是null通常更正确,它们代表不同的东西。试图解决这个问题的库就是在对抗JavaScript。

幸福的编码。


就我个人而言,在几乎所有情况下,我都避免显式检查undefinednull。我认为,在大多数情况下——但不是所有情况——所有的假值应该是相等的,调用者有责任遵守所述的公共契约。

由于这种信念,我认为比较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
' 't'r'n ' == 0 // true

"JavaScript: The Good Parts by Douglas Crockford "。版权所有2008雅虎!公司,978-0-596-51774-8。"