请实现 Lodash 的 .get()
2022年10月2日
💎 加入 E+ 成長計畫 與超過 300+ 位軟體工程師一同在社群中成長,並且獲得更多的軟體工程學習資源
Lodash 的 .get() 在做什么?
.get()
是很常被用到的一个效用函式,他做的事情是给定一个物件,以及某个路径,要回传此路径的值;如果该路径不存在于给定的物件,则返回预设值。透过例子会比较好理解 (以下例子来自 Lodash 原始码)
const object = { a: [{ b: { c: 3 } }] };
//=> 3
get(object, "a[0].b.c");
//=> 3
get(object, 'a[0]["b"]["c"]');
//=> 'default
get(object, "a[100].b.c", "default");
从上面的例子可以看到 Lodash 这个函式库,可以接收各种类型的路径,主要是原始码当中有castPath这个 helper function。 castPath
会把上面的"a[0].b.c"
、'a[0]["b"]["c"]'
以及"a[100].b.c"
都转成好处理的['a', '0', 'b', 'c']
。
因此,如果给定有内建的 castPath
,.get()
实际在做的事情是
// 给定一个物件,例如
const object = { a: [{ b: { c: 3 } }] };
// 给一个路径,透过 .get() 找到该路径的值,例如
get(object, ["a", "0", "b", "c"]); // 回传 3
实现 .get()
一起来看看如何实现 .get()
function lodashGet(object, path, defaultValue) {
// 先确认传进来的 object 不是 null,如果是则直接回传 defaultValue
if (object == null) {
return defaultValue;
}
let count = 0;
const length = path.length;
// 依循路径一层层走过该物件,以上面的例子来说,会是
// path[0] 为 'a',所以第一次回圈 object 会变成 object['a'] 也就是 [{ b: { c: 3 } }]
// 第一次回圈后,count 加 1,所以变成 object[path[1]]
// 也就是 [object['0']],意即 { b: { c: 3 } }
// 接着 count 再加一,所以 object 会成为 object[path[2]]
// 也就是 object['b'],意即 { c: 3 }
// 接着 count 再加一,所以 object 会成为 object[path[3]]
// 也就是 object['c'],意即 3
// 这时 count 为 4,由于 length 也是 4,因为 4 不小于 4,所以跳出回圈
while (object != null && count < length) {
object = object[path[count++]];
}
// 因为上面如果 object 是 null 的话,在走完 length 长度前,就会跳出 while 回圈
// 这种情况下,就代表依循该路径,会找不到值,所以会是 undefined
// 举例来说,如果 path 是 ['a', '1', 'b', 'c']
// 因为 object['1'] 会是 undefined,所以这时 while 回圈会在 count 为 2 时终止
// 这种情况下就会是 count < length,所以当 count < length,result 会是 undefined
const result = count && count == length ? object : undefined;
// 如果 result 是 undefined,代表依循该路径,会找不到值,所以回传预设值
// 如果依循路径有找到值,就回传 result
return result === undefined ? defaultValue : result;
}