动机:平时写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":"默认值"}}]}

手写 lodash/get、lodash/set 方法的更多相关文章

  1. 基于TensorFlow解决手写数字识别的Softmax方法、多层卷积网络方法和前馈神经网络方法

    一.基于TensorFlow的softmax回归模型解决手写字母识别问题 详细步骤如下: 1.加载MNIST数据: input_data.read_data_sets('MNIST_data',one ...

  2. C# 手写将对象转换为Json方法

    一.需求场景 (1)不能用JavaScriptSerializer.DataContractJsonSerializer.Newtonsoft.Json这些写好的方法,需要自己写方法. (2)转化的类 ...

  3. 使用神经网络来识别手写数字【译】(三)- 用Python代码实现

    实现我们分类数字的网络 好,让我们使用随机梯度下降和 MNIST训练数据来写一个程序来学习怎样识别手写数字. 我们用Python (2.7) 来实现.只有 74 行代码!我们需要的第一个东西是 MNI ...

  4. (手写识别) Zinnia库及其实现方法研究

    Zinnia库及其实现方法研究 (转) zinnia是一个开源的手写识别库.采用C++实现.具有手写识别,学习以及文字模型数据制作转换等功能. 项目地址 [http://zinnia.sourcefo ...

  5. 框架源码系列四:手写Spring-配置(为什么要提供配置的方法、选择什么样的配置方式、配置方式的工作过程是怎样的、分步骤一个一个的去分析和设计)

    一.为什么要提供配置的方法 经过前面的手写Spring IOC.手写Spring DI.手写Spring AOP,我们知道要创建一个bean对象,需要用户先定义好bean,然后注册到bean工厂才能创 ...

  6. gcd手写代码及STL中的使用方法

    一.手写代码 inline int gcd(int x,int y){ if(y==0) return x; else return(gcd(y,x%y)); } 二.STL中的使用方法 注:在STL ...

  7. 手写redux方法以及数组reduce方法

    reduce能做什么? 1)求和 2)计算价格 3)合并数据 4)redux的compose方法 这篇文章主要内容是什么? 1)介绍reduce的主要作用 2)手写实现reduce方法 0)了解red ...

  8. JavaScript手写new方法

    1.看一下正常使用的new方法 function father(name){ this.name=name; this.sayname=function(){ console.log(this.nam ...

  9. 前端进阶之认识与手写compose方法

    目录 前言:为什么要学习这个方法 compose简介 compose的实现 最容易理解的实现方式 手写javascript中reduce方法 redux中compose的实现 参考文章 最后 前言:为 ...

  10. 手写Promise中then方法返回的结果或者规律

    1. Promise中then()方法返回来的结果或者规律 我们知道 promise 的 then 方法返回来的结果值[result]是由: 它指定的回调函数的结果决定的 2.比如说下面这一段代码 l ...

随机推荐

  1. java try_catch 分析

    1.若一段代码前有异常抛出,并且这个异常没有被捕获,这段代码将产生编译时错误「无法访问的语句」.如 public class try_catch_Demo { public static void m ...

  2. U 跳转中加入变量参数的写法

    href="{:U('Message/news?id='.$vo['messageid'].'')}" 就是在U方法里如果参数是变量就用 '.$i.'代替 {$i} <a h ...

  3. Lazysysadmin靶机

    仅供个人娱乐 靶机信息 Lazysysadmin靶机百度云下载链接:https://pan.baidu.com/s/1pTg38wf3oWQlKNUaT-s7qQ提取码:q6zo 信息收集 nmap全 ...

  4. kivy八种布局方式学习

    kivy八种布局:FloatLayout.BoxLayout.AnchorLayout.GridLayout.PageLayout.RelativeLayout.ScatterLayout.Stack ...

  5. 给每个li延时添加样式动画效果(setInterval,clearInterval)

    btnsAnime($('ul li')) function btnsAnime(pagesl) { var that = this $(pagesl).hide() let i = 0; funct ...

  6. 用Autohotkey让Kitty命令行变得更好用

    下面的脚本实现Win+K键激活一个输入框,给出了kitty命令行常用的几种格式,基本可分为两种:连接保存好的模板(session)和完全手工连接,前者用-load加Session名称,后者需要在命令行 ...

  7. Shellshock 破壳漏洞 Writeup

    破壳漏洞 CVE编号:CVE-2014-6271 题目URL:http://www.whalwl.site:8029/ 提示:flag在服务器根目录 ShellShock (CVE-2014-6271 ...

  8. 《深入浅出vue.js》阅读笔记之数组变化侦测

    1.如何追踪变化 数组的侦测方式和对象不同,比如: this.list.push(1) 此时并不会像改变对象一样触发setter. 同理,要侦测数组的变化意味着我们在改变数组的时候得到通知,如图,我们 ...

  9. C#多线程详解(一) Thread.Join()的详解

    bicabo   C#多线程详解(一) Thread.Join()的详解 什么是进程?当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源.而一个进程又是由多个线程 ...

  10. Maven项目管理工具--简单实用与入门

    Maven管理的方式就是"自动下载项目所需要的jar包,统一管理jar包之间的依赖关系" Maven下载与安装 1.首先确保JDK已安装,且JDK为1.6+(尽量新,新肯定支持,旧 ...