一文10个示例讲懂鸿蒙系统ArkTS中的null与undefined的区别与应用-《精通HarmonyOS NEXT :鸿蒙App开发入门与项目化实战》读者福利

107 阅读7分钟

作为ArkTS语言的初学者,对于null与undefined的概念总会弄混,这两者有什么区别,应该如何按需的使用?相信读者们在具体的场景中使用时,都有一些疑惑。

本篇内容是《精通HarmonyOS NEXT :鸿蒙App开发入门与项目化实战》这本书第四章内容的延续,是咱这本书读者的福利,在本篇内容中通过10个示例说明在不同的场景中,null与undefined的区别与应用,每个示例可以独立的编译及调试,欢迎大家一同来深入的解这两者,甚至可以当作面试题来学习。

对本书感兴趣的同学可以点击以下链接进行购买,及参加 我的班级(华为官方)共同学习

往期福利:

  1. 【页面路由导航】三步实现页面跳转的完整示例-《精通HarmonyOS NEXT :鸿蒙App开发入门与项目化实战》读者福利

示例1: 基本定义和区别

声明一个变量(或常量,以下以变量通指变量或常量)可以为undefined,当这个变量未赋值,默认为 undefined。当声明一个变量可以为null,则需要对其进行指定默认值,否则会编译报错。

// 声明一个变量可以为undefined,当这个变量未赋值,默认为 undefined。
let uninitializedVar: string | undefined;
if (uninitializedVar == undefined) { // 条件表达式为真
  hilog.info(0x008666, '俩毛豆:testNullAndUndefind', "uninitializedVar is undefined");
}

// 当声明一个变量可以为null,则需要对其进行指定默认值,否则会编译报错。
let explicitlyNull: string | null = null;
if (explicitlyNull == null) { // 条件表达式为真
  hilog.info(0x008666, '俩毛豆:testNullAndUndefind', "explicitlyNull is null");
}
// 反例,当声明一个变量可以为null,没有指定默认值。
let explicitlyNullNotInit: string | null;
if (explicitlyNullNotInit == null) { // 编译报错 Variable 'explicitlyNullNotInit' is used before being assigned
  hilog.info(0x008666, '俩毛豆:testNullAndUndefind', "explicitlyNullNotInit is null");
}

对应的log输出及编译报错的截图

  • log输出

log

  • 编译报错

示例2: 类型检查差异

undefined类型的变量的类型为undefined,null类型的变量的类型为object。

// 使用示例1中的变量uninitializedVar
const typeofUninitializedVar = typeof uninitializedVar;
hilog.info(0x008666, '俩毛豆:testNullAndUndefind', typeofUninitializedVar); // 输出: "undefined"
// 使用示例1中的变量explicitlyNull
const typeofExplicitlyNull = typeof explicitlyNull;
hilog.info(0x008666, '俩毛豆:testNullAndUndefind', typeofExplicitlyNull);   // 输出: "object"

对应的log输出的截图

示例3: 相等性比较

undefined与null类型的宽松相等为true,严格相等为false

const nullEqqUndefined = null == undefined;
hilog.info(0x008666, '俩毛豆:testNullAndUndefind', nullEqqUndefined ? "true" : "false"); // 输出: "true" (宽松相等)
const nullEqqqUndefined = null === undefined;
hilog.info(0x008666, '俩毛豆:testNullAndUndefind', nullEqqqUndefined ? "true" : "false"); // 输出:" false" (严格相等)

对应的log输出的截图

示例4: 函数返回值

函数没有明确返回值时,返回 undefined,函数有明确返回为null时,需要显示的定义,且返回值可能为空

// 函数没有明确返回值时,返回 undefined
function noReturnValue(): void {
  // 没有return语句
}

// 函数有明确返回为null时,需要显示的定义,且返回值可能为空
function returnNullOrStr(): string | null {
  return null;
}
// 直接定义返回为空,也可以编译通过
function returnNull(): null {
  return null;
}

const noReturnValueType = noReturnValue();
hilog.info(0x008666, '俩毛豆:testNullAndUndefind', "" + noReturnValueType); // 输出: undefined
const returnNullType = returnNull();
hilog.info(0x008666, '俩毛豆:testNullAndUndefind', "" + returnNullType);    // 输出: null

对应的log输出的截图

示例5: 类对象属性访问

undefined属性在定义时可以不初始化,默认为undefined,null属性在定义时需要初始化。在创建类对象时,均需要指定初始值,否则会编译出错。

注意,可空属性在定义时可以不初始化,默认为undefined,在创建类对象时,可选指定初始值。

class Man {
  name: string = ""; // 必需要初始化
  age: number = 0;   // 必需要初始化
  address?: string | undefined; // 可以不初始化 默认值为 undefined
  addressUndefined: string | undefined; // 可以不初始化 undefined
  addressNull: string | null = ""; // 必需要初始化
}

// 字面量创建类对象实例
let man: Man = {
  name: "俩毛豆",
  age: 30,
  // 没有初始化address属性,可选
  addressUndefined: undefined,
  addressNull: null
};

hilog.info(0x008666, '俩毛豆:testNullAndUndefind', man.name); // 输出: "俩毛豆"
hilog.info(0x008666, '俩毛豆:testNullAndUndefind', "" + man.address); // 输出: undefined
hilog.info(0x008666, '俩毛豆:testNullAndUndefind', "" + man.addressUndefined); // 输出: undefined
hilog.info(0x008666, '俩毛豆:testNullAndUndefind', "" + man.addressNull); // 输出: undefined

对应的log输出的截图

示例6: 数字转换

undefined类型转换为数字为NaN,null类型转换为数字为0,定义的变量也如此。

const numberUndefined = Number(undefined);
hilog.info(0x008666, '俩毛豆:testNullAndUndefind', "" + numberUndefined); // 输出: NaN
// 使用示例1中的变量 uninitializedVar
hilog.info(0x008666, '俩毛豆:testNullAndUndefind', "" + Number(uninitializedVar)); // 输出: NaN
const numberNull = Number(null);
hilog.info(0x008666, '俩毛豆:testNullAndUndefind', "" + numberNull); // 输出: 0
// 使用示例1中的变量 explicitlyNull
hilog.info(0x008666, '俩毛豆:testNullAndUndefind', "" + Number(explicitlyNull)); // 输出: 0

对应的log输出的截图

示例7: 布尔转换

undefined类型转换为数字为false,null类型转换为数字为false,定义的变量也如此。

注意,这点与数字转换是有不同的

const boolNull = Boolean(null);
hilog.info(0x008666, '俩毛豆:testNullAndUndefind', "" + boolNull); // 输出: false
// 使用示例1中的变量 uninitializedVar
hilog.info(0x008666, '俩毛豆:testNullAndUndefind', "" + Boolean(uninitializedVar)); // 输出: false
const boolUndefined = Boolean(undefined);
hilog.info(0x008666, '俩毛豆:testNullAndUndefind', "" + boolUndefined); // 输出: false
// 使用示例1中的变量 explicitlyNull
hilog.info(0x008666, '俩毛豆:testNullAndUndefind', "" + Boolean(explicitlyNull)); // 输出: false

对应的log输出的截图

示例8: 空值合并操作符(??)

undefined与null类型的变量,在空值合并操作符的左侧时,该操作符的值为右侧的值

function greet(name: string | null | undefined) {
  // 如果name是undefined 或 null,使用默认值,常见于没有设定用户名时显示
  const displayName = name ?? "Guest"; //"Guest" 仅当左侧为 null 或 undefined 时生效。
  hilog.info(0x008666, '俩毛豆:testNullAndUndefind', `Hello, ${displayName}!`);
}

greet(undefined); // 输出: Hello, Guest!
greet(null); // 输出: Hello, Guest!
greet("俩毛豆"); // 输出: Hello, 俩毛豆!

对应的log输出的截图

示例9: 数组中的表现

undefined与null类型在数组中均占位,同时也会影响数组的类型

let array = [1, null, 3, undefined, 5];
hilog.info(0x008666, '俩毛豆:testNullAndUndefind', "" + array); // 输出: [1,,3,,5]
hilog.info(0x008666, '俩毛豆:testNullAndUndefind', "" + array[1]); // 输出: null
hilog.info(0x008666, '俩毛豆:testNullAndUndefind', "" + array[3]); // 输出: undefined
// 报错 Argument of type 'number[]' is not assignable to parameter of type 'string'. <ArkTSCheck>
hilog.info(0x008666, '俩毛豆:testNullAndUndefind', array);

对应的log输出和编译报错的截图

  • log输出

  • 编译报错提示,注意底部的array:(number | null | undefined)

示例10: JSON序列化差异

undefined类型的属性不会被序列化、而null类型的属性会被序列化

// 类定义
interface Student {
  name: string;
  age: number | null;
  score: number | undefined;
}
// 实例化
let student: Student = {
  name: "Bob",
  age: null, // 明确设置为null的属性
  score: undefined // 未定义的属性
};

// 注意: undefined属性不会被序列化
hilog.info(0x008666, '俩毛豆:testNullAndUndefind', JSON.stringify(student)); // 输出: {"name":"Bob","age":null}

对应的log输出的截图

总结:

undefined与null类型在我们研发过程中经常会用到,感兴趣的同学可以基于该内容之上再进行变种的验证。

对本书感兴趣的同学可以点击以下链接进行购买,及参加 我的班级(华为官方)共同学习