乐趣区

关于前端:关于-JavaScript-中-null-的一切

原文地址:Everything about null in JavaScript

原文作者:Dmitri Pavlutin

译者:Gopal

JavaScript 有两种类型:原始类型(strings, booleans, numbers, symbols)和对象

对象是一个简单的数据结构。最简略的 JavaScript 对象是一般对象 —— 键和相干值的汇合

let myObject = {name: 'Eric Cartman'};

然而很多状况下不能创立一个对象。在这种状况下,JavaScript 提供了一个非凡的值 null —— 示意短少对象

let myObject = null;

在这篇文章中,你将学习对于 JavaScript 中的 null 的所有: 它的含意,如何检测它,nullundefined 之间的区别,以及为什么大量应用 null 会造成代码保护艰难等

1.null 的概念

JavaScript 标准中这么形容 null

null 是一种原始类型,示意无意不蕴含任何对象值

如果您看到 null(调配给变量或由函数返回),那么在那个地位本来应该是一个对象,但因为某种原因,一个对象没有创立

比方,函数 greetObject() 创建对象,但也能够在无奈创建对象时返回 null:

function greetObject(who) {if (!who) {return null;}
  return {message: `Hello, ${who}!` };
}

greetObject('Eric'); // => {message: 'Hello, Eric!'}
greetObject();       // => null

当下面的函数中传入一个字符串参数时,如预期的,函数返回一个对象 {message: 'Hello, Eric!'}

然而,函数中不传任何参数时,该函数返回 null。返回 null 是正当的,因为 who 参数没有值,导致 greeting 对象无奈创立

1.1 null 的一个比拟贴切的比喻

思考对于 null 的一个比拟贴切的比喻,你能够把变量设想成一个盒子。就像变量能够包容对象一样,盒子也能够包容像茶壶等的物品

但一旦你收到一个盒子,关上它,什么也没有! 有人弄错了,给了你一个空盒子。该盒子不蕴含任何内容,或者换句话说,它蕴含一个 null

2. 如何去检测 null

查看 null 好办法是应用严格相等运算符

const missingObject = null;
const existingObject = {message: 'Hello!'};

missingObject  === null; // => true
existingObject === null; // => false

missingObject === null 的后果为 true,因为 missingObject 变量蕴含一个 null 值。如果变量蕴含非空值,比方对象,则表达式 existingObject === null 的后果为 false

2.1 null 是一个假值

nullfalse、0、”、undefinedNaN 都是假值。如果在条件语句中遇到它们,那么 JavaScript 将把它们强制为 false

Boolean(null); // => false

if (null) {console.log('null is truthy');
} else {console.log('null is falsy'); // logs 'null is falsy'
}

2.2 typeof null

typeof value 类型操作符能够确定值的类型。例如,类型为 15 的是 numbertypeof {prop: 'Value'} 等于 object

乏味的是,null 值类型的后果是什么

typeof null; // => 'object'

一个缺失的对象类型怎么被判断为 object? 原来 typoef null 作为 object 是晚期 JavaScript 实现中的一个谬误

不要应用 typeof 操作符检测 null 值。如前所述,应用严格的相等运算符 myVar === null

如果你想应用 typeof 去查看一个变量是否是一个对象,你必须排除掉 null 的状况

function isObject(object) {return typeof object === 'object' && object !== null;}

isObject({prop: 'Value'}); // => true
isObject(15);                // => false
isObject(null);              // => false

3. null 的陷阱

null 通常会在你心愿应用对象的状况下意外呈现。而后,如果尝试从 null 中提取属性,JavaScript 会抛出一个谬误

让咱们再次应用 greetObject() 函数并尝试从返回的对象中拜访 message 属性

let who = '';

greetObject(who).message; 
// throws "TypeError: greetObject() is null"

因为 who 变量是一个空字符串,所以函数返回 null。当从 null 拜访 message 属性时,将抛出类型谬误谬误

你能够通过应用 可选链操作符 来解决 null

let who = '';

greetObject(who)?.message ?? 'Hello, Stranger!';  
// => 'Hello, Stranger!'

或者应用下一节中形容的两种抉择。

4. null 的代替计划

当你不能结构一个对象时,很容易返回 null。但这种做法也有毛病

一旦 null 呈现在执行堆栈中,你总是必须查看它

咱们尽量避免返回 null

  • 返回默认对象而不是 null
  • 抛出谬误而不是返回 null

让咱们回顾一下 greetObject() 函数返回 greeting 对象

当短少参数时,能够返回一个默认对象,而不是返回 null

function greetObject(who) {if (!who) {who = 'Stranger';}
  return {message: `Hello, ${who}!` };
}

greetObject('Eric'); // => {message: 'Hello, Eric!'}
greetObject();       // => { message: 'Hello, Stranger!'}

或者抛出一个谬误

function greetObject(who) {if (!who) {throw new Error('"who" argument is missing');
  }
  return {message: `Hello, ${who}!` };
}

greetObject('Eric'); // => {message: 'Hello, Eric!'}
greetObject();       // => throws an error

这些实际能够让你完全避免解决 null

5. null vs undefined

undefined 就是未初始化的变量或对象属性的值

例如,如果在申明变量时没有赋初值,那么拜访该变量的后果为 undefined

let myVariable;

myVariable; // => undefined

nullundefined 之间的次要区别是,null 示意失落了的对象,而 undefined 示意未初始化的状态

严格相等运算符 === 辨别 nullundefined

null === undefined; // => false

而涣散相等运算符 == 则认为 nullundefined 相等

null == undefined; // => true

我应用涣散相等运算符查看变量是否为 nullundefined

function isEmpty(value) {return value == null;}

isEmpty(42);                // => false
isEmpty({prop: 'Value'}); // => false
isEmpty(null);              // => true
isEmpty(undefined);         // => true

6. 总结

nullJavaScript 中的一个非凡值,示意失落的对象

严格相等运算符判断变量是否为空: variable === null

typoef 操作符用于确定变量的类型 (number, string, boolean)。然而,typeofnull 状况下会引起误会: typeof null 后果为 object

nullundefined 在某种程度上是等价的,但 null 示意一个失落的对象,而 undefined 示意未初始化状态

尽可能防止返回 null 或将变量设置为 null。因为这种做法会导致 null 值的扩大和须要对 null 的验证。相同,尝试应用具备默认属性的对象,或者甚至抛出谬误会是更好的实际

你会应用什么办法来查看 null?

退出移动版