进阶4-2期Object.assign 原理及其实现 (转)
Posted zhaobao1830
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了进阶4-2期Object.assign 原理及其实现 (转)相关的知识,希望对你有一定的参考价值。
https://github.com/yygmind/blog/issues/26
浅拷贝 Object.assign
上篇文章介绍了其定义和使用,主要是将所有可枚举属性的值从一个或多个源对象复制到目标对象,同时返回目标对象。(来自 MDN)
语法如下所示:
Object.assign(target, ...sources)
其中 target
是目标对象,sources
是源对象,可以有多个,返回修改后的目标对象 target
。
如果目标对象中的属性具有相同的键,则属性将被源对象中的属性覆盖。后来的源对象的属性将类似地覆盖早先的属性。
示例1
我们知道浅拷贝就是拷贝第一层的基本类型值,以及第一层的引用类型地址。
let a = { name: "advanced", age: 18 } let b = { name: "muyiy", book: { title: "You Don‘t Know JS", price: "45" } } let c = Object.assign(a, b); console.log(c); // { // name: "muyiy", // age: 18, // book: {title: "You Don‘t Know JS", price: "45"} // } console.log(a === c); // true // 第二步 b.name = "change"; b.book.price = "55"; console.log(b); // { // name: "change", // book: {title: "You Don‘t Know JS", price: "55"} // } // 第三步 console.log(a); // { // name: "muyiy", // age: 18, // book: {title: "You Don‘t Know JS", price: "55"} // }
1、在第一步中,使用 Object.assign
把源对象 b 的值复制到目标对象 a 中,这里把返回值定义为对象 c,可以看出 b 会替换掉 a 中具有相同键的值,即如果目标对象(a)中的属性具有相同的键,则属性将被源对象(b)中的属性覆盖。这里需要注意下,返回对象 c 就是 目标对象 a。
2、在第二步中,修改源对象 b 的基本类型值(name)和引用类型值(book)。
3、在第三步中,浅拷贝之后目标对象 a 的基本类型值没有改变,但是引用类型值发生了改变,因为 Object.assign()
拷贝的是属性值。假如源对象的属性值是一个指向对象的引用,它也只拷贝那个引用地址。
示例2
String
类型和 Symbol
类型的属性都会被拷贝,而且不会跳过那些值为 null
或 undefined
的源对象。
// 第一步 let a = { name: "muyiy", age: 18 } let b = { b1: Symbol("muyiy"), b2: null, b3: undefined } let c = Object.assign(a, b); console.log(c); // { // name: "muyiy", // age: 18, // b1: Symbol(muyiy), // b2: null, // b3: undefined // } console.log(a === c); // true
Object.assign
模拟实现
实现一个 Object.assign
大致思路如下:
1、判断原生 Object
是否支持该函数,如果不存在的话创建一个函数 assign
,并使用 Object.defineProperty
将该函数绑定到 Object
上。
2、判断参数是否正确(目标对象不能为空,我们可以直接设置{}传递进去,但必须设置值)。
3、使用 Object()
转成对象,并保存为 to,最后返回这个对象 to。
4、使用 for..in
循环遍历出所有可枚举的自有属性。并复制给新的目标对象(使用 hasOwnProperty
获取自有属性,即非原型链上的属性)。
实现代码如下,这里为了验证方便,使用 assign2
代替 assign
。注意此模拟实现不支持 symbol
属性,因为ES5
中根本没有 symbol
。
以上是关于进阶4-2期Object.assign 原理及其实现 (转)的主要内容,如果未能解决你的问题,请参考以下文章
JS 原生方法原理探究:如何实现 Object.assign()?
JS-使用 Object.assign合并多个Object对象
使用 Object.assign 和 class/extends 有啥区别?