为什么JavaScript中有“null”值?

为什么JavaScript中有“null”值?,javascript,null,language-features,undefined,Javascript,Null,Language Features,Undefined,在JavaScript中,有两个值基本上表示“我不存在”——undefined和null 程序员未分配任何内容的属性将是未定义的,但为了使属性成为null,必须显式地将null分配给它 我曾经认为有必要使用null,因为undefined是一个原始值,null是一个对象。即使typeof null将产生'object',它也不是:实际上,这两个值都是原始值-这意味着未定义的和null都不能从构造函数返回,因为它们都将转换为空对象(必须抛出一个错误来声明构造函数失败) 在布尔上下文中,它们的计算结

在JavaScript中,有两个值基本上表示“我不存在”——
undefined
null

程序员未分配任何内容的属性将是
未定义的
,但为了使属性成为
null
,必须显式地将
null
分配给它

我曾经认为有必要使用
null
,因为
undefined
是一个原始值,
null
是一个对象。即使
typeof null
将产生
'object'
,它也不是:实际上,这两个值都是原始值-这意味着
未定义的
null
都不能从构造函数返回,因为它们都将转换为空对象(必须抛出一个错误来声明构造函数失败)

在布尔上下文中,它们的计算结果也都是
false
。我能想到的唯一真正的区别是,在数字上下文中,一个计算为
NaN
,另一个计算为
0

那么,如果程序员在试图确定是否设置了属性时错误地检查了
null
,那么为什么会同时存在
undefined
null

我想知道的是,是否有人有一个合理的例子,需要使用
null
,而不能用
undefined
来表示

因此,普遍的共识似乎是,
undefined
表示“没有这样的属性”,而
null
表示“属性确实存在,但没有价值”

如果JavaScript实现真的会强制执行这种行为,我可以接受,但是
undefined
是一个完全有效的原语值,因此可以很容易地将其分配给现有属性以打破这种约定。因此,如果要确保某个属性是否存在,必须使用
中的
运算符或
hasOwnProperty()
。那么,再一次问:
未定义的
空的
的单独值的实际用途是什么


当我想取消设置不再使用但我不想删除的属性值时,我实际上使用了
undefined
。我应该改用
null
吗?

两者都可以。例如,如果查询WMI,则完全可能有一个类返回具有空值的属性。它们是被定义的,它们恰好在当时保持为null。

最好的描述,但概括起来:

undefined表示缺少类型和值,null表示缺少值


此外,如果你在做简单的“==”比较,你是对的,它们的结果是一样的。但是try==,它比较了类型和值,你会注意到它们的区别。

从语义上讲,它们的意思不同。类型null在其域中只有一个值,null和一个属性可以被指定此特定值。未定义表示明显缺少已分配的任何值。

请尝试以下示例:

<html>
<head>
    <script type="text/javascript">
        function ShowObjProperties(obj) {
            var property, propCollection = "";

            for(property in obj) {
                propCollection += (property + ": " + obj[property] + "\n");
            }

            alert(propCollection);
        }

        var obj = {
            userid: 3,
            name: 'me!',
            speak: function() { alert('Hi! My name is ' + this.name + ' and my ID is ' + this.userid + '.'); }
        }

        //Shows all properties
        ShowObjProperties(obj);

        //The Speak function is no longer in the list!
        delete obj.speak;
        alert(typeof obj.speak);
        ShowObjProperties(obj);

        //The UserID is still listed, it just has no value!
        obj.userid = null;
        ShowObjProperties(obj);
    </script>
</head>
<body>

</body>
</html>

函数ShowObjProperties(obj){
var属性,propCollection=“”;
对于(obj中的属性){
propCollection+=(属性+”:“+obj[属性]+”\n”);
}
警报(propCollection);
}
var obj={
用户ID:3,
名字:“我!”,
speak:function(){alert('Hi!我的名字是'+this.name+',我的ID是'+this.userid+');}
}
//显示所有属性
showOBJ不动产(obj);
//Speak功能不再在列表中!
删除obj.speak;
警报(obj.speak的类型);
showOBJ不动产(obj);
//用户ID仍在列表中,只是没有值!
obj.userid=null;
showOBJ不动产(obj);

我认为这里有两种不同类型的Java脚本的真正用途。

归根结底是Java脚本的动态特性


事物可能是未定义的,以便以后可以添加它们。这就是javascript如此强大和可扩展的原因。

我认为您的结论是,javascript将
未定义的
定义为“没有这样的属性”,将
null
定义为“属性没有价值”,这是完全正确的。在像JavaScript这样动态的语言中,这是一个非常重要的区别。duck类型的使用意味着我们需要能够区分不存在的属性和没有值的属性。它是我们获取类型信息的主要手段。在静态类型语言中,字段为null和字段不存在之间存在明确的区别。在JavaScript中,这也不例外。但是,它会在运行时进行检查,并且可以在该时间之前进行修改

我不得不承认,这种实现很奇怪,因为很多时候这种区别是模糊的。然而,我认为在JavaScript中,这种区别很重要。能够分配
未定义的
是必不可少的

我记得不久前读过一篇关于用JavaScript编写的在线RPG的博文。它使用了一些示例,其中对象被创建为现有实例的副本,而不是原型(类、函数等等),然后被修改。这真的让我明白了
未定义的
在修改现有对象时有多么强大,但我不记得是谁写的。

问题并不是真的“JS中为什么有空值”-在大多数语言中都有某种空值,通常认为它非常有用

问题是,“为什么JS中有一个未定义的值”。主要使用地点:

  • 当您声明
    var x但不分配给它,
    x
    保持未定义状态
  • 当函数得到的参数少于它声明的参数时
  • 当您访问不存在的对象属性时
  • null
    
    // a key exists as a placeholder for something
    if(obj[name] === null) 
    // no key exists int eh hashtable that is in this object
    if(obj[name] === undefined)
    
    filter_func_pt = {
      date:function(d){ return Math.round(d.getTime()/1000);},
      user: null,
    }
    
    function transform(obj){
        var ret = {};
        for( var prop in obj){
           var f = filter_func_pt[prop];
           if(f)
              ret[prop] = f(obj);
           else if(filter_func_pt[prop] === null)
             continue;
           else
             ret[prop] == obj;
        }
      return ret;
    }
    
    var a = {
       date: new Date(),
       user: 'sam'
       votes: [23, 41, 55] 
    };
    
    var b = transform(a);
    
    /* b = {
     *    date: 1298582417
     *    votes: [23, 41, 55]
     * }
     */
    
    oElement.onclick >> null
    
    oElement.innerText >> ""