本文在个站同步发布,您可以在>>这里看到最新的文章。
1 定义
特别说明,本文中的undefined
和null
指变量的字面值:
undefined
:已声明但未初始化的变量值null
:未定义(不存在)的变量值
例如:
var var1: number;
var var2: number = null;
在以上代码中,var1
的值为undefined
,而var2
则被显式地定义为null
。
不过需要注意的一点是,使用typeof
查看上述变量var2
的类型时,返回值并不是null
:
console.log(typeof undefined); //'undefined'
console.log(typeof var1); //'undefined'
console.log(typeof null); //'object'
console.log(typeof var2); //'object'
2 null/undefined变量
2.1 常见场景举例
1、变量值为undefined
在Midway框架中,通常在Controller中通过装饰器写法声明需要接收的参数,例如:
// src/controller/user.ts
// POST /user/ HTTP/1.1
// Host: localhost:3000
// Content-Type: application/json; charset=UTF-8
//
// {"uid": "1", "name": "harry"}
import { Controller, Post, Body } from '@midwayjs/core';
@Controller('/user')
export class UserController {
@Post('/')
async updateUser(@Body('uid') uid: string): Promise<User> {
// id 等价于 ctx.request.body.uid
}
}
※以上代码摘自Midway (midwayjs.org)
此时,若客户端未在请求中传送需要的参数uid
,则uid = undefined
,因为uid
已被声明但尚未初始化。
2、变量值为null
进行数据库操作时,如果数据库中某个非必填字段的值为null
,那么相应的,Prisma ORM返回的字段属性值也为null
:
// ...前略
export class UserService {
@Inject
db:DB //注入
async updateUser(uid: string, data:User){
const res = await this.db.user.update({
where: { uid },
data,
});
}
}
update API的返回值为User
类型的JavaScript对象,假设表中的age
为非必填字段,且没有设置合适的初始值,那么上述代码中的res.age
就有可能为null
。
2.2 初始化
为保证代码的鲁棒性,理应在业务代码前先对可能出现undefined
、null
(下文统称为“空值”)的入参进行处理。
在JavaScript中常见的做法是使用||
运算符处理空值,例如:
uid = uid || '';
这段代码的出发点是,当uid
为空值时,执行uid = ''
。但由于||
运算符不仅会放行空值,还会放行0、false,因此当参数为数值型或布尔型时,需要使用typeof
结合三元运算符进行处理。
TypeScript语言考虑到上述情况,新增了一种名为Nullish Coalescing的运算符,也就是我们常说的双问号运算(??
)。这种运算支持识别null
、undefined
,在处理空值时不再需要对数值型和布尔型数据进行特判:
null ?? "Value";
// "Value"
undefined ?? "Value";
// "Value"
false ?? true;
// false
0 ?? 100;
// 0
"" ?? "n/a";
// ""
NaN ?? 0;
// NaN
※上述代码摘自这篇博文。
因此,我们可以这样对入参进行处理:
uid = uid ?? '';
3 判别
1、判别是否为null
或undefined
:
var x;
if(x==null){
console.log(`x is null or undefined`);
}
2、判断是否为null
:
if(x===null){
console.log(`x is null`);
}
注意,【不可以】使用typeof
进行判断,如果你忘了为什么,可以复习一下第1节的最后一个code block。
3、判断是否为undefined
:
if(typeof x === 'undefined'){
console.log(`x is undefined`);
}
4 鲁棒性写法
为防止对象或对象的某一个属性对象为空,导致代码报错,TypeScript提出了一种叫做“可选链?.
”的运算符,它的功能是:在访问对象属性的过程中遇到空值时,①立即停下,②返回undefined
。例如:
const obj =
{
branch1: {
}
}
console.log(obj.branch1?.emp1?.name); //undefined
※以上代码摘自这篇博文。
由于obj.branch.emp1
未定义,返回undefined
。
使用可选链运算符,就可以省去逐层判空的代码了。
【写在最后】
在ts中,
null
和undefined
也是数据类型。默认情况下,null
和undefined
是所有类型的子类型,正因为如此,它们才能作为字面值赋给其它类型的变量。
参考
文章参考的博文:
- 在 TypeScript 中检查 Null 和 Undefined | D栈 - Delft Stack
- JavaScript 判断 null 、undefined、NaN的可靠方法、验证以及注意事项 - CSDN博客
文章中提到的框架:
-
Midway (midwayjs.org)
-
Prisma 中文网 (nodejs.cn)