null和undefined详解

区别

当声明的变量还未被初始化时,变量的默认值为undefined。
null用来表示尚未存在的对象,常用来表示函数企图返回一个不存在的对象。

undefined == null // true
undefined === null // false

null是一个表示‘无’的对象,转为数值时为0;undefined是一个表示‘无’的原始值,转为数值时为NaN。

Number(null) // 0
5 + null // 5

Number(undefined) // NaN
5 + undefined // NaN

undefined表示‘缺少值’,就是此处应该有一个值,但是还没有定义。典型用法是:

  1. 变量被声明了,但还没有赋值时,就等于undefined。
  2. 调用函数时,应该提供的参数没有提供,该参数等于undefined。
  3. 对象没有赋值的属性,该属性的值为undefined。
  4. 函数没有返回值时,默认返回undefined。

null表示‘没有对象’,即该处不应该有值。典型用法是:

  1. 作为函数的参数,表示该函数的参数不是对象。
  2. 作为对象原型链的终点。

关于赋值

undefined可以被赋值,而null不可以被赋值:

  1. undefined、NaN和Infinity都是全局对象window的属性。既然是属性,当然可以赋值。然而这三个属性又是不可写的属性,即它们的内部特性[[writable]]为false,所以赋值无效。
  2. null是一个字面量,准确地说叫做Null字面量。与true和false类似。它们都属于js的保留字,换句话说它们都是值,与数字值123、字符串值’fttbar’一样,当然不能被赋值了。

特点

可以给undefined赋值,但是注意不要把它放到全局作用域:

function foo() {
    var undefined = 10;
    console.log(undefined);
}
foo(); // 10

function foo() {
    undefined = 10;
    console.log(undefined);
}
foo(); // undefined

通过Object.getOwnPropertyDescriptor方法,可以证明undefined是window对象的只读属性:

Object.getOwnPropertyDescriptor(window, 'undefined');

/** 输出:Object {value: undefined, writable: false,
enumerable: false, configurable: false} **/

在严格模式下,给undefined赋值会报错。因为严格模式下,禁止给对象的只读属性赋值:

function foo() {
    'use strict';
    undefined = 10;
    console.log(undefined); // TypeError
}
foo();

undefined和null的类型:

typeof undefined // 'undefined'
typeof null // 'object'

// 需要使用复合条件来检测null值得类型
var a = null;
(!a && typeof a === 'object'); // true