今天群友发的笔试题,感觉还挺有意思的,正好和前两天学的可选链有关系,正好拿来试试手,(●ˇ∀ˇ●)

题目

用尽量简洁的代码(尽量一行实现)编写一个可以深度安全取值的函数, 如 get(obj, ‘a[2].b.user.name’) ==> undefined

思路

看到安全取值这几个字,并且不论深度,我立马就想到了可选链 ?.
所以使用ES6 [] 对对象的读取和可选链应该可以解决

思考点:对象读取过程中,如果对象是基本类型或者普通对象,那么我们可以直接使用可选链,但某个属性是数组怎么办,就如例子中的 a[2] 因此,我们需要把数组单独分开来,也就是遇到[]时,使用正则把数字单独抽离出来(因为 . 运算读取对象属性是不能用数字的,因此可以放心)

使用技术点:
① ES6 对 对象读取的新方式 [‘属性名(数组就是index)’]
② 可选链运算 ?.

代码

  1. let obj = {
  2. a: [1, 2, { b: 3 }]
  3. }
  4. function get(obj, str) {
  5. let args = str.split(/[.\[\]]/g).filter(item => item)
  6. console.log("args:", args);
  7. return args.reduce((prev, curr) => {
  8. return prev?.[`${curr}`]
  9. }, obj)
  10. }
  11. console.log(get(obj, 'a[2].b'));
  12. console.log(get(obj, 'a[2].b.user.name'));

image.png
我们可以看出,结果是能成功的取到值的,并且使用可选链也很安全

简化一行:

不换行就是一行代码拉,直接return就是一行代码,不接受 battle (╯▔皿▔)╯

  1. function get(obj, str) {
  2. return str.split(/[.\[\]]/g).filter(item => item).reduce((prev, curr) => {
  3. return prev?.[`${curr}`]
  4. }, obj)
  5. }