2.3 null和undefined

关于null和undefined,有一个免费的视频可供学习,详见参考资料[3]。在JavaScript以及它的扩展TypeScript中,null和undefined表示不同的意思。

● 变量没有初始化:undefined。

● 变量不可用:null。

1.检查是否相等

事实上,两者都需要检查。有趣的是,在JavaScript中,用==进行比较时,null和undefined相等,如下所示。

推荐使用==null来检查undefined和null,因为你通常并不希望区分它们。

注意:你也可以执行==undefined,但==null更常用。

有一种例外情况,即我们接下来将要讨论的在根级别上的undefined。

2.检查根级别上的undefined

在上文中,我们建议使用==null来检查是否相等,但是不要把它用于根级别的检查。在严格模式下,如果使用foo,并且foo为undefined,那么你将会得到一个ReferenceError的异常,且整个调用堆栈都会展开。

提示:你应该使用严格模式。事实上,如果你使用模块模式,TypeScript的编译器将会自动插入与严格模式相关的代码。本书后面的章节将会提及此,你不必担心它。

因此,为了检查一个变量是否已经被定义,或者是否在全局作用域上,通常会使用typeof。

3.限制显式地使用undefined

因为TypeScript可以让你把结构与值分开记录,而不是像下面这样。

因此,你应该使用一个类型注解。

4.Node风格的回调函数

在Node风格的回调函数,如(err,somethingElse)=>{/*something*/}中,如果不存在任何错误,通常会把err设置为null。不管怎样,你通常只需要使用truthy进行检查即可。

当创建你自己的API(Application Programming Interface,应用程序编程接口)时,你可以使用null让它们保持一致。对于你自己的API,你应该关注它是否支持Promise。如果支持的话,你就不必因为缺少相应处理而烦恼了,因为你可以使用.then和.catch处理它们。

5.不要把undefined作为有效的表示方式

例如,使用undefined可能会让一个函数变得比较可怕。

而将它改写成如下这样,则会好很多。

6.JSON和序列化

JSON标准支持编码null,但是不支持undefined。当JSON编码具有null属性的对象时,这个属性将会包含null值;然而当一个属性undefined时,在编码后,它就会被删除。

因此,基于JSON的数据库支持null,但是不支持undefined。由于设置为null的属性是编码的,你可以通过在编码并将对象传输到远程存储之前,将属性值设置为null,来表达清除属性的意图。

将属性值设置为undefined可以节省存储和传输成本,因为这样不会对属性名称进行编码。但是,这会使清除值和缺失值的语义复杂化。

7.小结

TypeScript团队并不会使用null。TypeScript风格指南指出,不使用null并不会造成任何困难。Douglas Crockford(Web开发领域知名的技术权威人士之一,ECMAScript 2.0标准化委员会委员)认为使用null是一个糟糕的想法,我们应该都使用undefined。

然而,Node.js风格的代码库把Error的参数设置为null并作为标准,因为它表示“有些东西目前不可用”。我个人并不在意是否要区分这两者,因为大多数项目所使用的库都具有不同的观点,但是都使用==null来排除这两者。