瞎說系列之Object.assign入門

前言

過去的一個多月新接手了一個公司的老項目,在實現新需求的同時還須要對有些地方進行重構,故而致使了沒時間更新文章。最近趁着週末更新一篇關於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)
}

瀏覽器兼容性

clipboard.png

最後

感謝各位可以耐心的讀完,若有錯誤歡迎指正,讓咱們一塊兒進步。後續的內容,敬請期待。

相關文章
相關標籤/搜索