js和ts中的null与undefined

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

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是所有类型的子类型,正因为如此,它们才能作为字面值赋给其它类型的变量。

参考

文章参考的博文:

文章中提到的框架:

  • 20
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值