Null vs Undefined

本文翻译自 https://codeburst.io/javascript-null-vs-undefined-20f955215a2 , 作者 Brandon Morelli,翻译:Thomas Chan

刚接触 js 的话,可能会认为 nullundefined 很相似,其实不然,本文将列述 nullundefined 之间的不同点与相同点。

null 是什么?

null 有两个你必须知道的特征:

  • null 是空或者不存在的值
  • null 一定是被赋值的
    像这样,我们给变量 a 赋值 null:
    1
    2
    3
    4
    let a = null;

    console.log(a);
    // null

undefined 是什么?

undefined 通常是一个变量已经被声明,但是没有赋值,例如:

1
2
3
4
let b;

console.log(b);
// undefined

也可以给变量直接赋值为 undefined:

1
2
3
4
let c = undefined;

console.log(c);
// undefined

还有一种情况是从一个 object 里读取一个不存在的属性就返回 undefined:

1
2
3
4
var d = {};

console.log(d.fake);
// undefined

null 与 undefined 的相同点

在 JavaScript 里只有 6 个否定值

  • false
  • 0(zero)
  • “”(empty string)
  • null
  • undefined
  • NaN(Not A Number)

nullundefined 是其中两个。其他所有的值都是真值。

如果你还不太熟悉 js 里的真/假值,可以看下我之前的文章: == vs ===

另外 JavaScript 里有 6 个原始值:

  • Boolean
  • Null
  • Undefined
  • Number
  • String
  • Symbol

nullundefined 亦是其中两个。其他所有的值都是对象(objects, functions, arrays等等)。

有趣的是,用 typeof 测试 null,会返回 object(译者注:这可是个大坑):

1
2
3
4
5
6
7
8
let a = null;
let b;

console.log(typeof a);
// object

console.log(typeof b);
// undefined

这个特征是 JavaScript 诞生时就有的,基本上被当做最早的 JavaScript 实现的一个错误。

如果你还太熟悉 js 里的数据类型,可以看下我之前的文章: JavaScript 数据类型解析

null !== undefined

综上所述, nullundefined 是不同的,不过有一些共同点,所以 null 是严格不等于 undefined 的。

1
null !== undefined

但是,用不严格比较符的时候 null 是等于 undefined 的。

1
null == undefined

在 JavaScript 里,双等号判断相等时会进行隐式类型转换,所以是不严格的。

实际运用中的不同

上述所说都很好理解,那么 nullundefined 之间到底有啥具体不同?

我们来看下面的代码:

1
2
3
let logHi = (str = 'hi') => {
console.log(str);
}

我们创建了一个函数叫 logHi,有一个参数,且设置默认值为 hi,调用是这样:

1
2
logHi();
// hi

我们也可以传个参数覆盖默认值:

1
2
logHi('bye');
// bye

但是!undefined 是不会覆盖默认值的,而 null 则会。

1
2
3
4
5
logHi(undefined);
// hi

logHi(null);
// null

总结

  • null 是被赋值的,表示啥都没有
  • undefined 通常是一个变量已经被声明,但是没有赋值
  • nullundefined 都是否定值
  • nullundefined 都是原始值,不过奇葩的是 typeof null = object
  • null !== undefined 但是 null == undefined

译者注:按我的经验,实际项目中,函数对参数进行处理时,按业务逻辑区分,基本都是需要对参数判断 NaN, null 与 undefined 的。若你的参数是 object,就更需要判断,尤其是后端返回给你的数据

avatar

Thomas Chan

年轻就是暴躁,年轻就是不安分,年轻就是发脾气