過去的一個多月新接手了一個公司的老項目,在實現新需求的同時還須要對有些地方進行重構,故而致使了沒時間更新文章。最近趁着週末更新一篇關於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) }
感謝各位可以耐心的讀完,若有錯誤歡迎指正,讓咱們一塊兒進步。後續的內容,敬請期待。