为什么null在JavaScript中被认为是一个对象?
正在检查
if ( object == null )
Do something
和
if ( !object )
Do something
?
还有:
null和undefined之间的区别是什么?
为什么null在JavaScript中被认为是一个对象?
正在检查
if ( object == null )
Do something
和
if ( !object )
Do something
?
还有:
null和undefined之间的区别是什么?
当前回答
TLDR
undefined是JavaScript中的一个基本值,表示一个值的隐式缺失。未初始化的变量自动具有此值,而没有显式返回语句的函数则返回undefined。
null也是JavaScript中的一个基本值。它表示有意不存在对象值。JavaScript中的null被设计用来实现与Java的互操作性。
typeof null返回“object”,这是由于语言设计的特殊性,源于JavaScript与Java可互操作的需求。它并不意味着null是一个对象的实例。这意味着:给定JavaScript中的原语类型树,null是“对象类型原语”子树的一部分。下面将更详细地解释这一点。
细节
Undefined是一个基本值,表示一个值的隐式缺失。注意,直到1998年的JavaScript 1.3版本才可以直接访问undefined。这告诉我们,null是程序员在显式表示缺少某个值时使用的值。未初始化的变量的值自动为undefined。undefined是ECMAScript规范中独一无二的类型。
Null是一个基本值,表示对象值的故意缺失。null也是ECMAScript规范中独一无二的类型。
JavaScript中的null是为了实现与Java的互操作性而设计的,无论是从“外观”的角度还是从编程的角度(例如计划于1996年实现的LiveConnect Java/JS桥)。Brendan Eich和其他人都表达了对包含两个“缺少值”值的厌恶,但在1995年,Eich奉命“让[JavaScript]看起来像Java”。
布兰达:服从指令
如果我没有从管理层那里得到“让它看起来像Java”的命令, 而且我有更多的时间(很难理清这两个因果因素),那么我就会更喜欢一个自我式的“一切都是一个对象”。 方法:没有布尔,数字,字符串包装。没有undefined和null。 叹息。
为了适应Java的null概念,由于Java的强类型性质,它只能被分配给类型为引用类型的变量(而不是原语),Eich选择将特殊的null值定位在对象原型链的顶部(即引用类型的顶部),并将null类型作为“对象类型原语”集的一部分。
typeof运算符随后在1996年8月19日发布的JavaScript 1.1中加入。
来自V8博客:
Typeof null返回对象,而不是null,尽管null是一个 自己的类型。要理解为什么,考虑所有的集合 JavaScript类型分为两组: 对象(即对象类型) 原语(即任何非对象值) 因此,null意味着“没有对象值”,而undefined意味着“没有” 价值”。
按照这个思路,Brendan Eich设计了JavaScript 使typeof为右边的所有值返回'object', 即所有对象和空值,在Java的精神。这就是为什么 Typeof null === 'object',尽管规范有一个单独的null类型。
因此,Eich设计了基元类型的层次结构,以实现与Java的互操作性。这导致他将null与层次结构中的“对象类型原语”一起定位。为了反映这一点,当typeof不久后被添加到语言中时,他选择typeof null来返回“object”。
JavaScript开发人员对typeof null === "object"表示惊讶,这是弱类型语言(JavaScript)和另一种强类型语言(Java)之间的阻抗不匹配(或抽象泄漏)的结果,弱类型语言(JavaScript)同时具有null和未定义,而另一种强类型语言(Java)只有null,其中null被严格定义为引用类型(而不是基本类型)。
请注意,这一切都是合乎逻辑的、合理的、站得住脚的。typeof null === "object"不是bug,而是必须适应Java互操作性的二阶效应。
出现了许多不完善的反向合理化和/或惯例,包括undefined表示隐式缺少值,null表示有意缺少值;或者,undefined是一个值的缺失,null是一个具体的对象值的缺失。
与Brendan Eich的相关对话,为后人截屏:
其他回答
为了补充“undefined和null之间的区别是什么”的答案,请参阅JavaScript权威指南第6版,本页第41页:
你可能认为undefined表示系统级的,意外的, 或者类似错误的无值和null表示程序级, 正常的,或预期的价值缺失。如果你需要分配一个 将这些值传递给变量或属性或将其中一个值传递给 一个函数,null几乎总是正确的选择。
摘自Nicholas C. Zakas的《面向对象的Javascript原理》
但是为什么对象类型是空的呢?(事实上,TC39(设计和维护JavaScript的委员会)已经承认这是一个错误。你可以推断null是一个空对象指针,使“object”成为一个逻辑返回值,但这仍然令人困惑。)
尼古拉斯·扎卡斯(2014-02-07)。面向对象JavaScript的原则(Kindle位置226-227)。没有淀粉机。Kindle版。
也就是说:
var game = null; //typeof(game) is "object"
game.score = 100;//null is not an object, what the heck!?
game instanceof Object; //false, so it's not an instance but it's type is object
//let's make this primitive variable an object;
game = {};
typeof(game);//it is an object
game instanceof Object; //true, yay!!!
game.score = 100;
未定义的例子:
var score; //at this point 'score' is undefined
typeof(score); //'undefined'
var score.player = "felix"; //'undefined' is not an object
score instanceof Object; //false, oh I already knew that.
看看这个:
<script>
function f(a){
alert(typeof(a));
if (a==null) alert('null');
a?alert(true):alert(false);
}
</script>
//return:
<button onclick="f()">nothing</button> //undefined null false
<button onclick="f(null)">null</button> //object null false
<button onclick="f('')">empty</button> //string false
<button onclick="f(0)">zero</button> //number false
<button onclick="f(1)">int</button> //number true
<button onclick="f('x')">str</button> //string true
在Javascript中,null不是对象类型,而是原始类型。
有什么不同? Undefined指的是一个没有被设置的指针。 Null指的是空指针,例如有人手动将一个变量设置为Null类型
与未定义相比,null的另一个有趣之处在于它可以递增。 X = undefined x + + Y = null y + + console.log(x) // NaN .log Console.log (y) // 0
这对于为计数器设置默认数值非常有用。你有多少次在声明中把一个变量设为-1 ?