过去的一个多月新接手了一个公司的老项目,在实现新需求的同时还须要对有些地方进行重构,故而致使了没时间更新文章。最近趁着周末更新一篇关于Object.assign使用的文章。javascript
Object.assign()方法用于将全部可枚举的属性的值从一个或多个源对象复制到目标对象,它将返回目标对象。这里有两点须要注意:一、该方法复制的是可枚举的属性的值,不可枚举的属性不会处理。二、它返回的是一个对象。java
Object.assign(target,...sources)
const target = { a: 1 } const source1 = { b: 2 } const source2 = { c: 3 } Object.assign(target, source1, source2) console.log(target) // {a: 1, b: 2, c: 3}
注意:
若是目标对象与源对象的属性具备相同的键,或者多个源对象的属性具备相同的键,则后面对象的属性会覆盖前面对象的属性。数组
const target = { a: 1, b: 1 } const source1 = { b: 2, c: 2 } const source2 = { c: 3 } Object.assign(target, source1, source2) console.log(target) // {a: 1, b: 2, c: 3}
若是只传入了一个参数,则该方法会直接返回该参数。浏览器
const target = { a: 1 } Object.assign(target) console.log(target) // {a: 1} console.log(Object.assign(target) === target) // true
若是传入的参数不是对象,原始类型会被包装为对象。this
const target = Object.assign(1) console.log(target) // Number {1} typeof target // "object"
null和undefined没法被转为对象,因此若是把它们两个做为目标对象则会报错。spa
const target = Object.assign(null) const tar = Object.assign(undefined) // Cannot convert undefined or null to object
若是null和undefined做为源对象,则不会报错,由于基本数据类型被包装,null和undefined会被忽略。prototype
const target = Object.assign({a:1}, null) const tar = Object.assign({a:1}, undefined) // {a:1} const target1 = Object.assign(1, null) // Number {1}
若是null和undefined做为源对象中的属性值,则它们不会被忽略code
const target = Object.assign({ a: 1 }, { b: null }, { c: undefined }) console.log(target) // {a: 1, b: null, c: undefined}
复制一个对象对象
const target = Object.assign({}, { a: 1 }) console.log(target) // {a: 1}
拷贝symbol类型的属性blog
const target = Object.assign({}, { a: 1 }, { [Symbol('foo')]: 2 }) console.log(target) // {a: 1, Symbol(foo): 2}
拷贝的属性是有限制的,继承属性和不可枚举属性没法被拷贝。
const obj = Object.defineProperty({}, 'a', { enumerable: false, value: 1 }) console.log(obj) // {a: 1} const target = Object.assign({b: 2}, obj) console.log(target) // {b: 2}
如今把a属性变成可枚举的属性。
const obj = Object.defineProperty({}, 'a', { enumerable: true, value: 1 }) console.log(obj) // {a: 1} const target = Object.assign({b: 2}, obj) console.log(target) // {b: 2, a: 1}
接下来再看看基本数据类型的可枚举性。
注意:
首先基本数据类型会被包装成对象,null和undefined会被忽略。其次只有字符串的包装对象才可能有自身可枚举属性。
const v1 = "abc" const v2 = true const v3 = 10 const v4 = Symbol("foo") const target = Object.assign({}, v1, null, v2, undefined, v3, v4) console.log(target) // {0: "a", 1: "b", 2: "c"}
拷贝一个数组。该方法会把数组视为对象,同时在拷贝的时候经过位置来进行覆盖。
const target = Object.assign([1,2,3],[4,5]) console.log(target) // [4, 5, 3]
Object.assgin()实现的是浅拷贝。若是源对象中的某个属性的值也是对象,那么目标对象拷贝获得的是这个对象的引用,一旦这个对象发生改变,那么拷贝后的目标对象也作相应的改变。
let obj1 = { a: 0 , b: { c: 0}} let obj2 = Object.assign({}, obj1) console.log(JSON.stringify(obj2)) // {"a":0,"b":{"c":0}} obj1.a = 1 console.log(JSON.stringify(obj1)) // {"a":1,"b":{"c":0}} console.log(JSON.stringify(obj2)) // {"a":0,"b":{"c":0}} obj2.a = 2 console.log(JSON.stringify(obj1)) // {"a":1,"b":{"c":0}} console.log(JSON.stringify(obj2)) // {"a":2,"b":{"c":0}} obj1.b.c = 3 console.log(JSON.stringify(obj1)) // {"a":1,"b":{"c":3}} console.log(JSON.stringify(obj2)) // {"a":0,"b":{"c":3}}
至于深浅拷贝的区别以及如何实现的问题,会在以后的文章中详细说明。
class Person { constructor(x, y) { Object.assign(this, {x, y}) } }
Object.assign(someClass.prototype, { foo(x, y){ .... } })
Object.assign(target, ...sources)
const target = Object.assign({}, { a: 1 }) console.log(target) // {a: 1}
const DEFAULT_VALUE = { name: 'Joe', age: '27' } function foo(options) { return Object.assign({}, DEFAULT_VALUE, options) }
感谢各位可以耐心的读完,若有错误欢迎指正,让咱们一块儿进步。后续的内容,敬请期待。