【问题标题】:JavaScript undefined replaced with nullJavaScript undefined 替换为 null
【发布时间】:2011-07-26 17:30:34
【问题描述】:

在 JavaScript 中 undefined 可以重新分配,因此通常建议创建一个自执行函数来确保未定义实际上是未定义的。作为替代nullundefined 绝对是==,但是否有任何其他值大致等同于null/undefined

TLDR

基本上你可以安全地替换这个:

(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

编辑:

我从未见过有人实际上用“未定义”与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 是安全的,前提是您不打算将值强制转换为整数。这是一个非常极端的情况。

【问题讨论】:

    标签: javascript null undefined


    【解决方案1】:

    语言规范第 11.9.3 节中的 abstract equality algorithm 定义了 ==!=,它对它们进行了定义

    null == void 0
    null == null
    void 0 == null
    

    其中void 0 只是表示undefined 的可靠方式(见下文),因此您的问题的答案是肯定的,null 等于 undefined 和它本身,仅此而已。

    规范的相关部分是

    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
    

    来自language specification

    11.4.2 无效运算符

    产生式 UnaryExpression : void UnaryExpression 评估如下:

    1. expr 成为评估UnaryExpression/的结果。
    2. 致电GetValue(expr)
    3. 返回未定义

    因此,void 前缀运算符评估其参数并返回特殊值 undefined,而不管全局变量 undefined 已更改(或者是否定义了 undefined :)。

    编辑:响应 cmets,

    如果您正在处理区分两者的库代码,那么您需要处理差异。一些由语言委员会标准化的新库确实忽略了差异:JSON.stringify([void 0]) === "[null]",但是那里有太多代码可以巧妙地区别对待它们,还有其他差异:

    +(null) === 0
    isNaN(+undefined)
    
    "" + null === "null"
    "" + undefined === "undefined"
    

    如果您正在编写生成文本或序列化/反序列化的任何类型的库,并且您想将两者混为一谈,那么您不能通过 undefined 并期望它表现得像 null - 您需要明确地将您的输入标准化为一个或另一个。

    【讨论】:

    • 在上面的代码中使用null 就像使用void 0 一样容易。我还可以争辩说nullvoid 0 更容易阅读和输入。我的观点是,区分两者似乎没有任何价值。尽管 undefined 应该代表一个“未知值”,但实际上没有人遵守这个约定。因此,忽略所有存在的 undefined 并使用 obj==null 代替它似乎是有益的。
    • 谢谢,我不知道转换为整数时的值是什么。拥有NaN0 绝对是不同的。不过,[null].join('')[undefined].join('') 似乎是等价的。
    【解决方案2】:

    因为 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 等标准函数返回。参见 cmets。

    因此,在 Javascript 中,使用undefined 而不是null 通常更正确。它们都代表不同的事物。一个试图解决这个问题的库正在与 JavaScript 作斗争。

    编码愉快。


    就个人而言,几乎在所有情况下,我都避免显式检查undefinednull。我相信在大多数(但不是全部)情况下,所有错误值都应该是等效的,并且调用者有责任遵守所述公共合同。

    由于这种信念,我会考虑比较 x == null 处于试图保护太多但又太少的边缘,但在捕捉null undefined的情况下,正如所指出的,它有效。去开始一个趋势;-)

    【讨论】:

    • DOM 方法,例如 getElementById 返回 null,因为 undefined 的概念在 WebIDL 中不存在,规范中有一个 void 类型,但它仅用于操作没有任何价值。
    • 好的答案,还要补充:delete 产生的结果 (undefined) 与 = null 不同。
    • 人们实际上用undefined 表示“未知值”的频率是多少?我从未见过这种情况,这就是我最初问这个问题的原因。它只是看起来是两个令人难以置信的混淆值,它们从未在其原始意图中使用。标准化所有内容以进行比较obj==null 将有利于大小并避免重新分配的任何问题。一切都会继续工作var obj={};obj.nonExistantProperty==nullvar x;if(x==null);
    • @Lime 我的回答侧重于意义,而不是用于警卫。除非在 其中 null 被赋予特殊含义的情况下,x == null 会在它是 undefined(可能的情况)和 null 时捕获而不会造成伤害。但是,我会考虑将null 传递给函数 1) 一个正常的虚假值 2) 一个特殊的哨兵值,具体取决于函数合约。但是,正如您所指出的,条件检查确实会同时捕获这两种情况,因此如果期望两种情况都被捕获,那么它具有相同的语义。
    • @pst 很高兴看到一些生产代码,其中区分变量/属性的 undefinednull 对于可读性和功能很有价值,因为它似乎会增加持续的混乱。跨度>
    【解决方案3】:

    因为这个:

    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。

    【讨论】:

    • 我的意思是区分两者似乎没有任何价值。尽管undefined 应该代表一个“未知值”,但实际上没有人遵守这个约定。
    • 假设您从未将任何内容分配给未定义的值,那么能够区分未触及的变量和无效的变量是有价值的。不过,出于当今开发人员如何使用 JS 的所有实际目的,我可以理解您的观点......
    【解决方案4】:

    阅读 Javascript: The Good parts,似乎只有 null 和 undefined 是等价的

    JavaScript 有两组相等运算符:=== 和 !==,以及它们的邪恶双胞胎 == 和 !=。好的那些 以您期望的方式工作。如果两个操作数类型相同且值相同,则 === 产生真和 !== 产生假。当操作数是 相同的类型,但如果它们是不同的类型,它们会尝试强制转换这些值。他们这样做的规则 很复杂,难以忘怀。以下是一些有趣的案例:

    '' == '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:Douglas Crockford 的优秀部分。版权所有 2008 年 Yahoo! Inc., 978-0-596-51774-8。”

    【讨论】:

    • 最后一个太可怕了
    猜你喜欢
    • 2010-11-03
    • 2020-02-09
    • 2023-01-20
    • 2021-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-25
    • 2023-03-18
    相关资源
    最近更新 更多