动机:平时写js代码时经常遇到要使用 lodash 中 _.get 和 _.set 的情况,每次使用都要引用 lodash,总感觉很烦,能不能自己实现一个简单的方法来实现一样的功能呢?

get 方法实现

  1. get 方法接受三个参数,第一个是目标对象或者数组,第二个是获取值的路径,第三个是获取失败时的默认值
function get(object, path, defaultValue) {
// 判断 object 是否是数组或者对象,否则直接返回默认值 defaultValue
if (typeof object !== 'object') return defaultValue
// 沿着路径寻找到对应的值,未找到则返回默认值 defaultValue
return _basePath(path).reduce((o, k) => (o || {})[k], object) || defaultValue
}
// 处理 path, path有三种形式:'a[0].b.c'、'a.0.b.c' 和 ['a','0','b','c'],需要统一处理成数组,便于后续使用
function _basePath(path) {
// 若是数组,则直接返回
if (Array.isArray(path)) return path
// 若有 '[',']',则替换成将 '[' 替换成 '.',去掉 ']'
return path.replace(/\[/g, '.').replace(/\]/g, '').split('.')
}

set 方法实现

  1. set 方法同样接受三个参数,第一个是源对象或者源数组,第二个是设置值的路径,第三个是value
function set(object, path, value) {
if (typeof object !== 'object') return object;
_basePath(path).reduce((o, k, i, _) => {
if (i === _.length - 1) { // 若遍历结束直接赋值
o[k] = value
return null
} else if (k in o) { // 若存在对应路径,则返回找到的对象,进行下一次遍历
return o[k]
} else { // 若不存在对应路径,则创建对应对象,若下一路径是数字,新对象赋值为空数组,否则赋值为空对象
o[k] = /^[0-9]{1,}$/.test(_[i + 1]) ? [] : {}
return o[k]
}
}, object)
// 返回object
return object;
}

测试

let obj = { a: [{ b: { c: 6 } }] }
console.log(get(obj, 'a[0].b.c', '默认值')) // 6
console.log(get(obj, 'a.5.b.c', '默认值')) // '默认值'
console.log(get(obj, ['a', '0', 'b', 'c'], '默认值')) // 6 let obj1 = { a: [{ b: { c: 6 } }] }
let obj2 = { }
let obj3 = { }
set(obj1, 'a[0].b.c', '默认值')
set(obj2, 'a.0.b.5.c', '默认值')
set(obj3, ['1', '2', 'b', 'c'], '默认值')
console.log(JSON.stringify(obj1)) // {"a":[{"b":{"c":"默认值"}}]}
console.log(JSON.stringify(obj2)) // {"a":[{"b":[null,null,null,null,null,{"c":"默认值"}]}]}
console.log(JSON.stringify(obj3)) // {"1":[null,null,{"b":{"c":"默认值"}}]}

最新文章

  1. 在 Ubuntu 14.10 中借用 Windows 的字体
  2. ANSI Common Lisp Practice - My Answers - Chatper - 3
  3. [python]设计模式
  4. FA模块的10个API范例
  5. vc下的静态链接库与动态链接库(一)
  6. 跟我学Windows Azure 四 Cloud Service中的WebRole与WorkRole,及他们之间的通信
  7. 【Win10 UWP】微信SDK基本使用方法和基本原理
  8. ajax for in eval()知识点的应用
  9. 32+激发灵感的HTML5/CSS3网页设计教程
  10. uva 10706 Number Sequence(数学规律)
  11. Struts2技术详解(转)
  12. jQuery + json 实现省市区三级联动
  13. hdu4681 String DP(2013多校第8场)
  14. 【Android】给Android Studio设置代理
  15. java使用redis数据库
  16. 装饰器模式&&ES7 Decorator 装饰器
  17. Maven&&Philosophy~
  18. JS onclick跳转
  19. pyCharm最新激活码(2018激活码)
  20. 源项目 -> fork -> 本地 (如何把源项目的代码合并到本地然后推送给fork)

热门文章

  1. jvm源码解读--13 gc_root中的栈中oop的mark 和copy 过程分析
  2. Floyd弗洛伊德算法
  3. js之检测浏览器
  4. sql server 查看数据库配置等信息(字符集,编码格式,版本号...)
  5. artDialog 简单几种用法
  6. 关于MySQL8的WITH查询学习
  7. Nat Comm | 中科院动物所张勇团队合作揭示动物中DNA转座子介导基因重复的机制
  8. 文件上传之WAF绕过及相安全防护
  9. Vue实现点击按钮进行文件下载(后端Java)
  10. Socket通信-服务端