为什么undefined是一种数据类型

5

最近我在调试代码时发现 undefined 是一种数据类型,而 null 是一个对象。

我认为它们都属于数据类型。

我检查了 typeof undefinedtypeof null。它们分别返回 "undefined""object"

typeof undefined 
"undefined"

typeof null
"object"

能有人解释一下这种奇怪的行为吗。


你认为 typeof null === 'null' 吗? ^^ - john Smith
@john Smith 不,但我没有预料到这种行为。 - user3278797
@Venky:当出现您没有预期的行为时,您应该解释您预期的行为而不是其他行为。否则我们无法帮助您... - Lightness Races in Orbit
它们都是内置关键字。但是每个实体都有一个类型,为null创建一个新类型,当它已经完全适合类型系统时,这将是一个倒退的步骤。 - Lightness Races in Orbit
实际上,@LightnessRacesinOrbit,“undefined”不是内置关键字。(在我看来,这是另一个错误 - 这就是为什么你会看到人们使用“void 0”的原因) - Benjamin Gruenbaum
显示剩余2条评论
3个回答

4

nulltypeof 为 object 是一个早期的错误 - 当他们试图在 Chrome 夜间版中进行更正(变成 typeof null === "null")时,太多的东西依赖于当前的行为,太多的代码崩溃了。

未设置为正常值的 JavaScript 对象通常有三种状态:

  1. 未声明。
  2. 未定义。
  3. 明确为无。

未声明

例如 - 这种情况:

 y++; //I did not declare y before, this causes a reference error
 y === 'undefined'; //still a reference error 
 typeof y; //'undefined', since typeof is an operator and not a function.

基本上,未声明的变量处于“脚本不知道此变量”的状态。

未定义

这意味着运行时“知道此变量”,但它尚未设置为任何值。或者,正如语言规范所述:

未定义的值-当变量未被赋值时使用的原始值。

例如:

 var y; //y is undefined
 y === undefined; //true, y defined the line above
 typeof y; //undefined, but this is redundant, just do `=== undefined`
 (function(x){ /* x is undefined here as it was set to nothing*/})()

明确的空值

当你有一个本应该有值的东西,但你想声明它是空的时候,就可以使用明确的空值。或者,正如语言规范所说:

空值 - 表示任何对象值故意缺失的原始值。

例如,如果给定ID的元素不在DOM中,则document.getElementById("foo");返回null,表示明确地返回了空值。与没有返回语句的函数不同,它们返回默认值undefined


那么你是在说这是Chrome的bug吗?还是你是在说Chrome在这个领域引领了JavaScript的发展? - Lightness Races in Orbit
1
@LightnessRacesinOrbit 这是一个 JavaScript 的 bug,在工作组(TC39)和 ESDiscuss(邮件列表)中有关于修复它的讨论 - 在 Chrome canary 中尝试过,但失败了。 - Benjamin Gruenbaum
@BenjaminGruenbaum: 真希望当时我知道那个讨论,我会提交一些评论的。这种行为是完全合理的。 - Lightness Races in Orbit
@LightnessRacesinOrbit,欣赏 https://mail.mozilla.org/pipermail/es-discuss/2013-July/032282.html。另外,随时欢迎您在ESDiscuss上提出您的论点。 - Benjamin Gruenbaum
@BenjaminGruenbaum:谢谢,我会在有时间的时候仔细阅读所有内容 :) - Lightness Races in Orbit
显示剩余2条评论

2
他们有不同的类型,原因在于它们的存在方式不同:undefinednull在概念上并不相同。正如this answer所说的那样: undefined是缺乏类型和值,而null则是缺乏值。但我更喜欢应用一个现实世界的比喻:物质与暗物质。 undefined就像不存在的物质。它没有形式或实质,因此没有有意义的类型。当某个东西不应被视为存在时,您可以将其设置为undefinednull,另一方面,在计算机科学领域中描述了一个未知状态的对象。它仍然是一个对象,但我们不知道这个对象或其值是什么。(在这个意义上,它类似于数字NaN,它仍然是一个概念上的数字:我们只是不知道是什么数字。)Nullity用作未知值的占位符,而不是没有值的东西。它是存在的暗物质,以对象的形式存在,但由于我们没有任何关于它的类型的信息,因此没有更多的信息可用。
JavaScript理解这一点。因此,历史上nulltypeof'object'undefinedtypeof'undefined'有些人说这是一个遗留的错误自JavaScript诞生以来;我更喜欢说这是JavaScript诞生时的常识。
JavaScript 中的一个 bug 是 null === nullvar o = {x:undefined}; 'x' in o; // true,这两种情况都不应该出现。

2
值得一提的是,“那些人”说这是一个遗留问题,他们是语言的创造者。你的看法很有趣,但它并不是语言的作者们所想或正在处理的问题。同时也值得一提的是,这也不是语言规范所规定的。我同意null !== null会是一个非常有趣的实验,除了maybeNull === null之外,在高层次的角度上,null === null几乎没有任何意义。还要注意的是,例如o = {x:undefined}意味着'x' in o; // true'y' in o; // false - Benjamin Gruenbaum
@BenjaminGruenbaum:是的,我认为该句子下面的链接清楚地表明了这是工作组的意见。然而,对我来说,他们是谁或者他们创造了什么并不重要——无论如何,我都不同意他们的观点。至于后一个例子,我认为那是一种语言错误;在两种情况下都应该是“false”。 - Lightness Races in Orbit
你不必喜欢语言或委员会做出的任何设计选择,但事实就是这样。我强烈鼓励你参与并表达你的关切和意见 :) - Benjamin Gruenbaum
@BenjaminGruenbaum:那么进一步值得一提的是,ECMAScript 的创造者并没有发明空值的概念,也没有未定义性的概念。 :) - Lightness Races in Orbit

0
MDN文档中,他们给出了null被视为对象的原因:
typeof null === 'object'; // This stands since the beginning of JavaScript

是啊!这是一个好理由... 我猜他们自己也不理解,因此是设计错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接