ECMAScript 2020 的可选链运算符遇到的问题及解决方案

前言

随着前端技术的发展,我们需要处理越来越复杂的数据结构。然而,当我们试图访问嵌套的属性时,如果其中有一个属性为 null 或者 undefined,很容易导致程序崩溃。而 ECMAScript 2020 为我们提供了一种新的解决方案,即可选链运算符 ?.

本文将介绍可选链运算符的使用方式、遇到的问题以及解决方案,并提供示例代码。

可选链运算符

可选链运算符是 ECMAScript 2020 新增的运算符,用于在访问对象属性或方法时,避免发生 undefinednull 引用错误。

例如,我们要访问对象 person 的属性 name

const name = person.name; // 如果 person 为 null 或 undefined,则会抛出错误

但是,使用可选链运算符后,我们可以这样写:

const name = person?.name; // 如果 person 为 null 或 undefined,则返回 undefined,不会抛出错误

同样,当我们需要访问嵌套的属性时,可选链运算符也很有用。例如,我们需要访问对象 person 的属性 addressstreet

const street = person.address.street; // 如果 address 或者 person 为 null 或 undefined,则会抛出错误

使用可选链运算符:

const street = person?.address?.street; // 如果 address 或 person 为 null 或 undefined,则返回 undefined,不会抛出错误

另外,可选链运算符也可以用于函数调用:

const age = person?.getAge?.(); // 如果 getAge 函数不存在,则返回 undefined,不会抛出错误

可选链运算符非常简单易用,可以让我们更加安全、高效地访问对象的属性和方法。但是,在实际使用中也需要注意一些细节。

遇到的问题及解决方案

在 React 中使用可选链运算符

在 React 中,我们经常需要访问 props 中的属性或方法。使用可选链运算符可以有效地避免 undefined 或者 null 引用错误。例如:

function AwesomeComponent(props) {
  const title = props?.data?.title;
  // ...
}

然而,在使用 Babel 转码器时,需要安装 @babel/plugin-proposal-optional-chaining 这个插件,否则可能会出现语法错误。

.babelrc 文件中添加:

{
  "plugins": [
    "@babel/plugin-proposal-optional-chaining"
  ]
}

使用可选链运算符时需要注意的细节

在使用可选链运算符时,需要注意以下几点:

  1. 可选链运算符仅适用于 .,不能使用在 [] 中。

  2. 如果需要使用函数调用,需要确保它返回的是一个方法,而不是 undefined 或者 null。例如:

    const age = person?.getAge?.(); // 如果 getAge 函数返回 undefined,则 age 也会是 undefined,无法区分函数不存在和函数返回 undefined 两种情况。

    解决方案:

    使用默认值运算符 ?? 来对返回值为 undefinednull 的函数调用结果进行处理。例如:

    const age = person?.getAge?.() ?? '未知'; // 如果 getAge 函数不存在或者返回 undefined 或 null,则 age 为 '未知'
  3. 在某些情况下,使用可选链运算符会导致一些意想不到的结果。例如:

    const obj = { a: null }
    const value = obj?.a?.b?.c // value 为 undefined,这种情况下无法区分属性 b 是否存在

    解决方案:

    在需要访问的属性之后加上默认值运算符 ?? 或者逻辑 || 运算符,以确保当属性不存在时返回正确的默认值。例如:

    const value = obj?.a?.b?.c ?? '未知'; // 如果属性 b 或 c 不存在,则 value 为 '未知'

示例代码

下面是一些使用可选链运算符的示例代码,帮助大家更好地理解可选链运算符的使用方式和注意事项。

// 访问嵌套属性
const data = {
  user: {
    name: 'Tom',
    address: {
      city: 'Shanghai',
      street: 'Nanjing Road'
    }
  }
}
const city = data.user?.address?.city; // 如果 address 或者 user 为 null 或 undefined,则返回 undefined,不会抛出错误
console.log(city); // 'Shanghai'

// 使用默认值
const age = data.user?.age ?? 20; // 如果 age 不存在,则 age 为 20
console.log(age); // 20

// 函数调用
const getAge = data.user?.getAge?.(); // 如果 getAge 函数不存在,则返回 undefined,不会抛出错误
const defaultAge = getAge ?? 18; // 如果函数返回 undefined,则为其设置默认值
console.log(defaultAge); // 18

// 属性不存在时返回默认值
const obj = { a: null }
const value = obj?.a?.b?.c ?? '未知'; // 如果属性 b 或 c 不存在,则 value 为 '未知'
console.log(value); // '未知'

总结

在处理复杂的数据结构时,避免发生 undefinednull 引用错误是必不可少的。可选链运算符为我们提供了一种更为简便、高效的处理方法,可以大大提高代码的可读性和安全性。在使用可选链运算符时,需要注意一些细节和常见问题,并及时进行处理。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/659053f1eb4cecbf2d5bfcf7


纠错
反馈