手写lodash的set方法

8/21/2021 lodash

# 手写lodash的set方法

lodash的set方法提供了三个参数,可以快速给对象的某个节点赋值,本文介绍用手写方法实现的基本思路。

  1. # lodash的set方法

首先介绍下lodash库,这是一个比较实用的第三方工具库。其特点是一致性、模块化、高性能,它的最大特点就是对对象类型(object、array)的处理。
其中,它的_set方法也非常简单好用,参数只有三个,objpathvalue,分别代表要处理的对象、路径、要修改的值。

  1. # 手写lodash的set方法

该方法是手写lodash的set方法中本人觉得最酷的一种方法,充分利用了JavaScript的移位以及array的reduce方法,使代码变得十分简洁灵动。分析方法见注释

function mySet(obj, path, value){
    if (Object(obj) !== obj) return obj; // 如果不是一个对象,直接返回;这里可以过滤掉非object,array类型的变量
    
    if (!Array.isArray(path)) path = path.toString().match(/[^.[\]]+/g) || [];  //如果路径不是数组,而是'.aa[0].bb[1]' 形式的路径字符串,则用正则转换成数组形式
    path.slice(0,-1).reduce((a, c, i) => // 路径用reduce来迭代,最后一个元素不参与迭代
         Object(a[c]) === a[c] // 判断对象的下一个节点是不是还是对象,
             // 如果是,按照路径走
             ? a[c] 
             // 如果不是,根据情况赋予[]或者{}
             : a[c] = Math.abs(path[i+1])>>0 === +path[i+1] // 移位0位可以使得非数值变成0,+操作符可以使得字符串向数值转换,如果是字符串,会转变成NAN,所以这里在判断下一个路径是不是数字,如果是数字,则相等,赋值数组,否则是字符串,赋值对象;
                   ? [] 
                   : {}, // No: assign a new plain object
         obj)[path[path.length-1]] = value; // 最后一个元素作为key,用value给其赋值
    return obj; // 
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15