cannot read property of undefined报错的五种解决方案

·  阅读 1122

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动

在我们日常开发过程中,代码编写过程中稍不留神取值时、接口返回的数据不符合预期时就会在控制台看到cannot read property of undefined报错

导致报错的代码:

const obj = {
  name: 'nordon',
  info: {
    age: ''
  }
};

if(obj.msg.age === 18) { // Uncaught TypeError: Cannot read properties of undefined (reading 'age')
  console.log('年龄18岁')
}
复制代码

上述代码在取值的过程中便会报错,因为obj.msgundefined,导致取值age属性的时候是不存在的,因此在我们开发过程中,需要保证在取值过程中需要对每一次取值的结果进行验证,只有每一次取值结果符合期望才可以执行取值操作

常见处理方式:

&&短路运算符进行可访问性嗅探:

if(obj.msg && obj.msg.age === 18) {}
复制代码

|| 单元设置默认保底值:

if((obj.msg || {}).age === 18) {}
复制代码

try catch捕获异常:

try {
    if(obj.msg.age === 18) {}
} catch {
    // todo ...
}
复制代码

上述&& 和 || 两种种方式针对简单的数据结构是可以的,比较简单直观,二try catch的方式对代码的侵入性较高,不易过于频繁使用,而我们的取值操作是一件非常高频的事情,不可能每一次取值都要加try catch来进行容错处理

若是存在深层嵌套结构时:

const obj = {
    user: {
        info: {
            hobbys: {
                sports: [
                    {
                        value: "basketball",
                        label: "篮球",
                    },
                    {
                        value: "football",
                        label: "足球",
                    },
                ],
            },
        },
    },
};
复制代码

此时若是使用&& 和 || 的方式进行代码健壮性处理:

if(
  obj &&
  obj.user &&
  obj.user.info &&
  obj.user.info.hobbys &&
  obj.user.info.hobbys.sports &&
  obj.user.info.hobbys.sports[1] &&
  obj.user.info.hobbys.sports[1].value === 'basketball'
) {
   // todo...
}
复制代码

看着上述密密麻麻的判断,是不是心情顿时就不好了,因此&& 和 || 的方式将会使代码变得十分臃肿,不是很合适,可以手动封装一个根据传入的参数获取值

手动封装函数:

/**
 * keys: 数组,按照层递关系组成
 * source: 数据源
 */
const getValue = (keys, source) => {
    return keys.reduce((nextObj, key) => {
        return nextObj && nextObj[key] ? nextObj[key] : null;
    }, source);
};
复制代码

使用方式:

getValue(["user", "info", "hobbys", "sports", [1]], obj); // { value: 'football', label: '足球' }
getValue(["user", "info", "hobbys", [1]], obj); // null
复制代码

Optional chaining(可选链操作符):

可选链操作符( ?. )允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。?. 操作符的功能类似于 . 链式操作符,不同之处在于,在引用为空(nullish ) (null 或者 undefined) 的情况下不会引起错误,该表达式短路返回值是 undefined。与函数调用一起使用时,如果给定的函数不存在,则返回 undefined

使用语法:

const obj = {
  foo: {
    bar: {
      baz: 42,
    },
  },
};

const baz = obj?.foo?.bar?.baz; // 42
const safe = obj?.qux?.baz; // undefined
复制代码

在babel中使用:

下载:

npm install --save-dev @babel/plugin-proposal-optional-chaining
复制代码

在配置文件中配置,例如babel.config.js

{
  "plugins": ["@babel/plugin-proposal-optional-chaining"]
}
复制代码

然后就可以愉快的在项目中使用了

分类:
前端