为什么JavaScript中有一个`null`值?
在JavaScript中,有两个基本上说'我不存在'的值 - undefined
和null
。
程序员没有分配任何东西的属性将是undefined
,但为了使属性变为null
,必须明确地将null
分配给它。
我曾经认为需要null
因为undefined
是一个原始值, null
是一个对象。 它不是,即使typeof null
会产生'object'
:实际上,它们都是原始值 - 这意味着从构造函数函数中既不会返回undefined
也不会返回null
,因为两者都会被转换为空对象(必须抛出一个错误宣布建设者失败)。
它们在布尔上下文中都评估为false
。 我能想到的唯一真正的区别是,在数值上下文中,一个评估为NaN
,另一个评估为0
。
那么,为什么存在undefined
和null
如果这只会让试图查明属性是否已设置或者没有设置时错误地检查null
程序员感到困惑?
我想知道的是,如果任何人有一个合理的例子,在这里必须使用null
,而不能用undefined
来表示。
所以普遍的共识似乎是, undefined
意思是“没有这样的财产”,而null
意味着“财产确实存在,但没有价值”。
如果JavaScript实现能够实际执行此行为,我可以忍受这一点 - 但undefined
是一个完全有效的原始值,因此可以轻松地将其分配给现有属性以打破此合约。 因此,如果你想确定一个属性是否存在,你必须使用in
运算符或hasOwnProperty()
。 所以再次说明: undefined
和null
单独值的实际用途是什么?
我实际上使用undefined
时候,我想取消不再使用但不想delete
的属性值。 我应该使用null
吗?
这个问题并不是真的“为什么JS中有一个空值” - 在大多数语言中都有某种空值,它通常被认为非常有用。
问题是,“为什么JS中存在未定义的值”。 主要使用地点:
'null'肯定会对(1)和(2)*起作用。 (3)应该立即抛出一个异常,而事实上它不会,而是返回这个奇怪的'未定义',以后失败,这是调试困难的一个重要来源。
*:你也可以争辩说(2)应该抛出一个异常,但是你必须为default / variable参数提供一个更好,更明确的机制。
然而,JavaScript本来并没有例外,也没有任何方法可以问一个对象,如果它有一个特定名称的成员 - 唯一的方法是(有时仍然是)访问该成员,看看你得到了什么。 考虑到'null'已经有了一个目的,你可能想要为它设置一个成员,所以需要一个不同的带外值。 所以我们有'未定义',正如你指出的那样,它是有问题的,这是另一个伟大的JavaScript'功能',我们将永远无法摆脱。
我实际上使用未定义的时候,我想取消不再使用但不想删除的属性值。 我应该使用null吗?
是。 如果其他语言可能会抛出异常,请将“未定义”保留为信号的特殊值。
'空'通常更好,除了一些IE DOM接口,其中设置为'null'可以给你一个错误。 通常在这种情况下设置为空字符串往往工作。
最好在这里描述,但总结如下:
未定义的是缺少一个类型和值,而null则缺乏一个值。
而且,如果你正在做简单的'=='比较,你是对的,它们也是一样的。 但尝试===,它会比较类型和价值,你会注意到不同之处。
我不认为有任何理由同时存在null
和undefined
,因为许多人提出的唯一原因(“ undefined
意味着没有这样的变量/属性”)是无效的,至少在JavaScript中是这样。 undefined
不能告诉你变量/属性是否存在。
console.log(foo); // "ReferenceError: foo is not defined"
// foo does not exist
var foo;
console.log(foo); // "undefined", a different response
console.log(foo === undefined); // "true", but it does exist
var obj = {};
console.log(obj.hasOwnProperty("foo")); // "false", no such property
obj.foo = undefined;
console.log(obj.hasOwnProperty("foo")); // "true", it exists and has the value "undefined"
console.log(obj.foo === undefined); // "true", but it does exist
obj.bar = "delete me";
obj.bar = undefined;
console.log(obj.hasOwnProperty("bar")); // "true", not actually deleted
delete obj.bar;
console.log(obj.hasOwnProperty("bar")); // "false", deleted
正如你所看到的,检查foo === undefined
不会告诉你是否foo
存在,并设置obj.bar = undefined
并不是真正的删除bar
。
这可能是JavaScript作者最初的意图, undefined
应该代表“不存在”。 但是,实施并非如此。