标题和内容可能无关(微笑数组
Object.assign()相信你们都不陌生,就算平时没怎么用,也可能有在各种文章中见过它。在如此高的曝光率背后,咱们的assign是否是能承接咱们全部的寄托了?貌似是不能的:(cdn
最近在开发产品配置的后台,常常要对表单数据进行合并,因此常常用到咱们的主角Object.assign,用起来也十分方便,直到有一次遇到这个问题--对象
两个对象合并以后,结果却不符合预期,assign方法的后参数对象覆盖了前参数对象,按照对这个方法的直观理解,是应该输出图中的第一个结果才对。blog
深感疑惑的打开了MDN,看到了关于Object.assign的这样一句解释:递归
针对深拷贝,须要使用其余方法,由于 Object.assign()拷贝的是属性值。假如源对象的属性值是一个指向对象的引用,它也只拷贝那个引用值。开发
这样就能解释上面那个不符预期的结果了,Object.assign()拷贝的是属性值,若是属性值是对象,它只会拷贝引用值,也就形成了“覆盖”的假象了。既然知道了缘由,咱们是否能够搞一个assign的升级版,让它把引用值的属性也进行拷贝,恰好看到MDN里面有关于它的polyfill,代码以下--字符串
不难发现,assign的核心就是枚举对象的键值进行比对,而后得出拷贝的结果,那么咱们的改造重心应该也是循环的这块内容。几经折腾,写了个assignPro方法--string
在新的方法中,将以前循环赋值的地方换成了一个新的方法handleR,在里面将会对传入的对象进行递归解构赋值,检测到传入的键值是非数组对象,则将其做为参数再传入handleR方法中,直到遍历完全部的对象。产品
最终使用assignPro可使拷贝结果达到预期~请注意,这个玩意并无在生产中运用,你们抱着看看的心态就行了,固然若是可以继续完善,好比对数组的处理...最后应该仍是能够投入生产使用的。it
最后顺带的讲一下拷贝吧,assign能够看作单层的深拷贝,若是真的想深拷贝某个对象,最方便的方法就是用JSON.stringify把对象转成字符串,再用JSON.parse把字符串转成新的对象。你们有兴趣的话能够试试看~
此次的小技巧到这就结束啦,你们遇到assign结果不符合预期的时候也不用慌,由于这是正常操做:)