为什么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的相关对话,为后人截屏:
其他回答
使用null来定义没有值的东西,使用undefined当你期望一些东西可能根本没有定义。
例如,如果一个变量没有值,将其赋值为null。
var weDontHaveAValue = null;
如果你期望某些东西可能根本没有定义,例如一个可选的选项参数,使用undefined。
if (typeof args.optionalParam !== 'undefined') { }
Null是一个对象。它的类型是null。Undefined不是一个对象;其类型是未定义的。
看看这个:
<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
差异可以总结为以下代码片段:
alert(typeof(null)); // object
alert(typeof(undefined)); // undefined
alert(null !== undefined) //true
alert(null == undefined) //true
检查
Object == null与检查if (! Object)不同。
后者等于!布尔(对象),因为一元!运算符自动将右操作数转换为布尔型。
因为布尔(null)等于false,那么!false === true。
因此,如果对象不是null,而是false或0或"",检查将通过 因为:
alert(Boolean(null)) //false
alert(Boolean(0)) //false
alert(Boolean("")) //false
Undefined意味着一个变量已经声明,但它没有被赋值,而Null可以赋给一个变量,表示“没有值”。(Null是赋值运算符)
2.Undefined是一个类型本身,而Null是一个对象。
3.Javascript本身可以将任何未赋值的变量初始化为undefined,但它永远不能将变量的值设置为null。这必须通过编程来完成。