为什么null在JavaScript中被认为是一个对象?

正在检查

if ( object == null )
      Do something

if ( !object )
      Do something

?

还有:

null和undefined之间的区别是什么?


当前回答

Null是一个对象。它的类型是null。Undefined不是一个对象;其类型是未定义的。

其他回答

差异可以总结为以下代码片段:

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
typeof null;      // object
typeof undefined; // undefined

null值表示有意不存在任何对象值。它是JavaScript的基本值之一,在布尔操作中被视为假值。

var x = null;
var y;

X被声明并定义为null

Y声明了,但没有定义。它声明时没有值,所以没有定义。

Z没有被声明,所以如果你试图使用Z,它也是未定义的。

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的相关对话,为后人截屏:

下面的函数说明了原因,并能够计算出差异:

function test() {
        var myObj = {};
        console.log(myObj.myProperty);
        myObj.myProperty = null;
        console.log(myObj.myProperty);
}

如果你打电话

test();

你要

未定义的 零

第一个console.log(…)尝试在myObj尚未定义时从myProperty获取myProperty -因此它返回“未定义”。在将其赋值为null后,第二个console.log(…)显然返回“null”,因为myProperty存在,但它的值为null。

为了能够查询这种差异,JavaScript有null和undefined:而null就像在其他语言中是一个对象一样,undefined不能是一个对象,因为没有可用的实例(甚至不是空实例)。

(name is undefined)

你:你叫什么名字?(*) JavaScript:名字?名字是什么?我不知道你在说什么。你从来没提过任何名字。你在(客户端)看到其他脚本语言了吗?

name = null;

你:你叫什么名字? JavaScript:我不知道。

简而言之,未定义是指事物没有概念存在;它没有类型,在此范围内从未被引用过;Null是已知对象存在的位置,但不知道值是多少。

需要记住的一件事是,null在概念上与false或""或诸如此类的不一样,即使它们在类型转换后相等,即。

name = false;

你:你叫什么名字? 布尔值为false。

name = '';

你:你叫什么名字? JavaScript:空字符串


*: name在此上下文中的意思是一个从未定义过的变量。它可以是任何未定义的变量,然而,name是几乎任何HTML表单元素的属性。它可以追溯到很久以前,在id之前就设立了。它很有用,因为id必须是唯一的,但名称不必是唯一的。