首页 前端知识 js和ts中的null与undefined

js和ts中的null与undefined

2024-05-28 09:05:39 前端知识 前端哥 791 27 我要收藏

本文在个站同步发布,您可以在>>这里看到最新的文章。

1 定义

特别说明,本文中的undefinednull指变量的字面值:

  • 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 初始化

为保证代码的鲁棒性,理应在业务代码前先对可能出现undefinednull(下文统称为“空值”)的入参进行处理。

在JavaScript中常见的做法是使用||运算符处理空值,例如:

uid = uid || '';

这段代码的出发点是,当uid为空值时,执行uid = ''。但由于||运算符不仅会放行空值,还会放行0、false,因此当参数为数值型或布尔型时,需要使用typeof结合三元运算符进行处理。

TypeScript语言考虑到上述情况,新增了一种名为Nullish Coalescing的运算符,也就是我们常说的双问号运算(??)。这种运算支持识别nullundefined,在处理空值时不再需要对数值型和布尔型数据进行特判:

null ?? "Value";
// "Value"

undefined ?? "Value";
// "Value"

false ?? true;
// false

0 ?? 100;
// 0

"" ?? "n/a";
// ""

NaN ?? 0;
// NaN

※上述代码摘自这篇博文。

因此,我们可以这样对入参进行处理

uid = uid ?? '';

3 判别

1、判别是否为nullundefined

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中,nullundefined也是数据类型。默认情况下,nullundefined是所有类型的子类型,正因为如此,它们才能作为字面值赋给其它类型的变量。

参考

文章参考的博文:

  • 在 TypeScript 中检查 Null 和 Undefined | D栈 - Delft Stack
  • JavaScript 判断 null 、undefined、NaN的可靠方法、验证以及注意事项 - CSDN博客

文章中提到的框架:

  • Midway (midwayjs.org)

  • Prisma 中文网 (nodejs.cn)

转载请注明出处或者链接地址:https://www.qianduange.cn//article/9753.html
标签
后端
评论
发布的文章
大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!