如何处理 ES11 中的可选链操作符的 TypeError

如何处理 ES11 中的可选链操作符的 TypeError

在 ES11 中,新添加了可选链操作符(Optional Chaining Operator),可以让我们在访问一个对象时,不必担心对象不存在或者深度访问对象时会抛出 TypeError 异常。但是即使使用了可选链操作符,有时候仍然会遇到类型错误(TypeError)异常。本文将介绍可选链操作符的使用及解决 TypeError 异常。

可选链操作符的使用

可选链操作符是一个 ?,可以跟在一个对象的属性或方法调用后面,表示如果这个对象存在,就继续访问下去,如果不存在,则返回 undefined。示例如下:

const obj = {
  name: 'Alice',
  age: 18,
  address: {
    city: 'Shanghai'
  }
};

const cityName = obj.address?.city; // "Shanghai"
const countryName = obj.address?.country; // undefined

在上面的代码中,obj.address?.city 表示如果 obj.address 存在,则获取其 city 属性,否则返回 undefined。而 obj.address?.country 中的 obj.address 不存在,所以直接返回 undefined。

可选链操作符可以链式使用,如下所示:

const obj = {
  name: 'Alice',
  age: 18,
  address: {
    city: 'Shanghai',
    location: {
      lat: 31.22,
      lng: 121.46
    }
  }
};

const latitude = obj.address?.location?.lat; // 31.22

在上面的代码中,obj.address?.location?.lat 表示如果 obj.address 存在,并且它的 location 属性存在,则获取 locationlat 属性,否则返回 undefined。

TypeError 异常的解决

即使使用了可选链操作符,在访问一个未定义的属性或方法时,仍然会抛出 TypeError 异常。例如:

const obj = {
  name: 'Alice',
  age: 18,
  address: {
    city: 'Shanghai'
  }
};

const countryName = obj.address.country.toUpperCase(); // TypeError: Cannot read property 'toUpperCase' of undefined

在上面的代码中,obj.address.country 不存在,因此访问它的 toUpperCase 方法会抛出 TypeError 异常。

解决 TypeError 异常的方法就是在使用可选链操作符时,加上对 undefined 的判断,这样可以避免访问未定义的属性或方法。例如:

const obj = {
  name: 'Alice',
  age: 18,
  address: {
    city: 'Shanghai'
  }
};

const countryName = obj.address?.country?.toUpperCase(); // undefined

在上面的代码中,obj.address?.country?.toUpperCase() 表示如果 obj.address 存在,且它的 country 存在,则将 country 转成大写字母,否则返回 undefined。

案例分析

下面通过一个实际的案例来介绍如何使用可选链操作符和处理 TypeError 异常。

假设我们有一个对象数组,其中每个对象都代表一本书的信息,包括书名、作者和出版日期。我们想要通过一个日期范围(开始日期和结束日期)来筛选出所有出版日期在该范围内的书籍。

首先,我们可以写一个筛选函数 filterBooksByDateRange,如下所示:

function filterBooksByDateRange(books, startDate, endDate) {
  return books.filter(book => {
    const publishedDate = new Date(book.publishedDate);
    return publishedDate >= startDate && publishedDate <= endDate;
  });
}

其中,books 是一个对象数组,startDateendDate 分别是开始日期和结束日期。在函数中,我们通过 filter 方法遍历每个 book,然后将 publishedDate 转成日期对象,和 startDateendDate 比较来判断这本书是否符合我们的日期范围条件。

但是,如果某个 bookpublishedDate 属性不存在,那么将抛出 TypeError 异常。我们可以使用可选链操作符来避免这个问题,代码如下所示:

function filterBooksByDateRange(books, startDate, endDate) {
  return books.filter(book => {
    const publishedDate = new Date(book.publishedDate?.toString());
    return publishedDate >= startDate && publishedDate <= endDate;
  });
}

在上面的代码中,我们使用了可选链操作符 book.publishedDate?.toString() 来获取 publishedDate 的字符串表示,如果 publishedDate 不存在,则返回 undefined。然后我们调用 new Date() 来将字符串转化为日期对象,这样即使 publishedDate 不存在,也不会抛出 TypeError 异常了。

总结

可选链操作符是一个方便的工具,能够在访问对象时避免出现未定义的属性或方法访问问题。但是在使用可选链操作符时,我们仍然要注意可能出现的 TypeError 异常,需要加上对 undefined 的判断。我们可以通过案例分析来理解和掌握可选链操作符和解决 TypeError 异常的技巧。

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


纠错反馈