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

其他回答

什么是类型?

类型是对值进行分类的一种方式。下面是一个包含有问题的类型及其typeof结果的表格。

Type Values type contains typeof result Is typeof result a lie?
Undefined Only: undefined "undefined" No
Null Only: null "object" Yes
Object Infinite amount of values: {}, {a: "b"}, ... "object" No

null不是一个对象,它是一个null类型的值。

typeof操作符在说谎!它返回“object”为空在JavaScript语言中是一个错误。

我在我的开源电子书中写了一章。你可以在这里阅读https://github.com/carltheperson/advanced-js-objects

JavaScript中许多不同的null检查的比较:

http://jsfiddle.net/aaronhoffman/DdRHB/5/

// Variables to test
var myNull = null;
var myObject = {};
var myStringEmpty = "";
var myStringWhiteSpace = " ";
var myStringHello = "hello";
var myIntZero = 0;
var myIntOne = 1;
var myBoolTrue = true;
var myBoolFalse = false;
var myUndefined;

...trim...

http://aaron-hoffman.blogspot.com/2013/04/javascript-null-checking-undefined-and.html

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

思考“null”的最佳方式是回忆一下类似的概念是如何在数据库中使用的,在数据库中它表示字段包含“根本没有值”。

是的,物品的价值是已知的;它是“被定义的”。已经初始化。 该项的值是:“没有值。”

This is a very useful technique for writing programs that are more-easily debugged. An 'undefined' variable might be the result of a bug ... (how would you know?) ... but if the variable contains the value 'null,' you know that "someone, somewhere in this program, set it to 'null.'" Therefore, I suggest that, when you need to get rid of the value of a variable, don't "delete" ... set it to 'null.' The old value will be orphaned and soon will be garbage-collected; the new value is, "there is no value (now)." In both cases, the variable's state is certain: "it obviously, deliberately, got that way."

理解null和undefined的一种方法是了解它们出现的位置。

在以下情况下期望返回空值:

查询DOM的方法 console.log (window.document.getElementById(“nonExistentElement”)); / /输出:零 从Ajax请求接收到的JSON响应


    {
      name: "Bob",
      address: null
    }

RegEx.exec。 新功能处于不断变化的状态。下面返回null:


        var proto = Object.getPrototypeOf(Object.getPrototypeOf({}));

       // But this returns undefined:

        Object.getOwnPropertyDescriptor({}, "a");

所有其他不存在的情况都用undefined表示(由@Axel指出)。以下每一个都打印为“undefined”:

    var uninitalised;
    console.log(uninitalised);

    var obj = {};
    console.log(obj.nonExistent);

    function missingParam(missing){
        console.log(missing);
    }

    missingParam();

    var arr = [];
    console.log(arr.pop());        

当然,如果你决定写var unitialized = null;或者你自己从一个方法中返回null,那么你在其他情况下也会出现null。但这应该是很明显的。

第三种情况是当你想访问一个变量,但你甚至不知道它是否已经声明。在这种情况下,使用typeof来避免引用错误:

if(typeof unknown !== "undefined"){
    //use unknown
}

总之,在操作DOM、处理Ajax或使用某些ECMAScript 5特性时检查是否为空。对于所有其他情况,检查undefined严格相等是安全的:

if(value === undefined){
  // stuff
}