對象的常用方法

1. Object.assign()

Object.assign() 方法用于將所有可枚舉屬性的值從一個或多個源對象分配到目標(biāo)對象鹏秋。它將返回目標(biāo)對象。

語法: Object.assign(target, ...sources)

參數(shù):

  • target: 目標(biāo)對象招驴。
  • sources: 源對象痊臭。

返回值: 目標(biāo)對象

const target = { a: 1, b: 2 }
const source = { b: 4, c: 5 }

const returnedTarget = Object.assign(target, source)

target // { a: 1, b: 4, c: 5 }
returnedTarget // { a: 1, b: 4, c: 5 }

如果只有一個參數(shù),Object.assign會直接返回該參數(shù)雅倒。

const obj = {a: 1}

Object.assign(obj) // {a: 1}
Object.assign(obj) === obj // true

如果該參數(shù)不是對象嫁佳,則會先轉(zhuǎn)成對象挨队,然后返回。

typeof Object.assign(2) // "object"

由于undefined和null無法轉(zhuǎn)成對象蒿往,所以如果它們作為參數(shù)盛垦,就會報錯。

Object.assign(undefined) // 報錯
Object.assign(null) // 報錯

注意點(diǎn):

(1)淺拷貝

Object.assign方法實行的是淺拷貝瓤漏,而不是深拷貝腾夯。也就是說,如果源對象某個屬性的值是對象蔬充,那么目標(biāo)對象拷貝得到的是這個對象的引用俯在。

const obj1 = {a: {b: 1}}
const obj2 = Object.assign({}, obj1)

obj1.a.b = 2
obj2.a.b // 2

復(fù)制代碼上面代碼中,源對象obj1的a屬性的值是一個對象娃惯,Object.assign拷貝得到的是這個對象的引用。這個對象的任何變化肥败,都會反映到目標(biāo)對象上面趾浅。

(2)同名屬性的替換

對于這種嵌套的對象愕提,一旦遇到同名屬性,Object.assign的處理方法是替換皿哨,而不是添加浅侨。

const target = { a: { b: 'c', d: 'e' } }
const source = { a: { b: 'hello' } }
Object.assign(target, source)
// { a: { b: 'hello' } }

上面代碼中,target對象的a屬性被source對象的a屬性整個替換掉了证膨,而不會得到{ a: { b: 'hello', d: 'e' } }的結(jié)果如输。這通常不是開發(fā)者想要的,需要特別小心央勒。

一些函數(shù)庫提供 Object.assign的定制版本(比如 Lodash_.defaultsDeep方法)不见,可以得到深拷貝的合并。

(3)數(shù)組的處理 Object.assign可以用來處理數(shù)組崔步,但是會把數(shù)組視為對象稳吮。

Object.assign([1, 2, 3], [4, 5])
// [4, 5, 3]

上面代碼中,Object.assign把數(shù)組視為屬性名為 0井濒、1灶似、2 的對象,因此源數(shù)組的 0 號屬性4覆蓋了目標(biāo)數(shù)組的 0 號屬性1瑞你。

(4)取值函數(shù)的處理

Object.assign只能進(jìn)行值的復(fù)制酪惭,如果要復(fù)制的值是一個取值函數(shù),那么將求值后再復(fù)制者甲。

const source = {
  get foo() { return 1 }
}
const target = {}

Object.assign(target, source)
// { foo: 1 }

上面代碼中春感, source對象的foo屬性是一個取值函數(shù),Object.assign不會復(fù)制這個取值函數(shù)过牙,只會拿到值以后甥厦,將這個值復(fù)制過去。

用法

Object.assign方法有很多用處寇钉。

(1)為對象添加屬性

class Point {
  constructor(x, y) {
    Object.assign(this, {x, y})
  }
}

上面方法通過Object.assign方法刀疙,將x屬性和y屬性添加到Point類的對象實例。

(2)為對象添加方法

Object.assign(SomeClass.prototype, {
  someMethod(arg1, arg2) {
    ···
  },
  anotherMethod() {
    ···
  }
})

// 等同于下面的寫法
SomeClass.prototype.someMethod = function (arg1, arg2) {
  ···
}
SomeClass.prototype.anotherMethod = function () {
  ···
}

上面代碼使用了對象屬性的簡潔表示法扫倡,直接將兩個函數(shù)放在大括號中谦秧,再使用assign方法添加到SomeClass.prototype之中。

(3)克隆對象

function clone(origin) {
  return Object.assign({}, origin)
}

上面代碼將原始對象拷貝到一個空對象撵溃,就得到了原始對象的克隆疚鲤。

不過,采用這種方法克隆缘挑,只能克隆原始對象自身的值集歇,不能克隆它繼承的值。如果想要保持繼承鏈语淘,可以采用下面的代碼诲宇。

function clone(origin) {
  let originProto = Object.getPrototypeOf(origin)
  return Object.assign(Object.create(originProto), origin)
}

(4)合并多個對象

將多個對象合并到某個對象际歼。

const merge = (target, ...sources) => Object.assign(target, ...sources)

如果希望合并后返回一個新對象,可以改寫上面函數(shù)姑蓝,對一個空對象合并鹅心。

const merge = (...sources) => Object.assign({}, ...sources)

2. Object.keys()、Object.value()纺荧、Object.entries()

(1)Object.keys() 返回一個包含該對象所有的鍵的數(shù)組旭愧。

用法

let user = {
  name: 'IU',
  age: 18
}

const keyList = Object.keys(user) 
console.log(keyList) // ["name", "age"]

// 可以使用 Array.prototype.includes() 方法檢查數(shù)組中是否存在鍵。
const val = 'age'

if (keyList.length > 0) {
  if(keyList.includes(val)){
    console.log('存在 key')
  } else {
    console.log('不存在 key')
  }
}

// 計算屬性數(shù)量
const count = (obj) => Object.keys(obj).length

count(user) // 2


(2)Object.values(obj) 返回一個包含該對象所有的值的數(shù)組宙暇。

let user = {
  name: 'IU',
  age: 18
}

// 遍歷所有的值
for (let value of Object.values(user)) {
  console.log(value)
}

// IU
// 18

用法

屬性求和

let price = {
  HTML: 99,
  JavaScript: 299,
  CSS: 199
}

方式一:使用 Object.values 和 for..of 循環(huán)返回所有數(shù)的總和

const sumPrice = (val) => {
  let sum = 0
  for (let salary of Object.values(val)) {
    sum += salary
  }
  return sum
}

sumPrice(price) // 650

方式二:使用 Object.values 和 reduce 來求和

const sumPrice = (val) => Object.values(val).reduce((a, b) => a + b, 0)
sumPrice(price) // 650

(3)Object.entries(obj) 返回一個包含該對象所有 [key, value] 鍵值對的數(shù)組输枯。

let user = {
  name: 'IU',
  age: 18
}

for (const [key, value] of Object.entries(user)) {
  console.log(`${key}: ${value}`)
}

// name: IU
// age: 18

注意

  • Object.keys/values/entries 方法都是用 Object. 來調(diào)用。

  • Object.keys/values/entries 會忽略 symbol 屬性

  • 就像 for..in 循環(huán)一樣客给,這些方法會忽略使用 Symbol(...) 作為鍵的屬性用押。
    如果我們想要 Symbol 類型的鍵,可以 Object.getOwnPropertySymbols() 方法 靶剑,它會返回一個只包含 Symbol 類型的鍵的數(shù)組蜻拨。另外,還有一種方法 Reflect.ownKeys(obj)桩引,它會返回所有鍵缎讼。

3. Object.defineProperty()

Object.defineProperty() 方法會直接在一個對象上定義一個新屬性,或者修改一個對象的現(xiàn)有屬性坑匠,并返回此對象血崭。

語法: Object.defineProperty(obj, prop, descriptor)

參數(shù)

  • obj: 要定義屬性的對象。
  • prop: 要定義或修改的屬性的名稱或 Symbol 厘灼。
  • descriptor: 要定義或修改的屬性描述符夹纫。

具體用法可以參照Vue雙向綁定原理這一部分,這里有對該方法的詳細(xì)介紹设凹。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末舰讹,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子闪朱,更是在濱河造成了極大的恐慌月匣,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件奋姿,死亡現(xiàn)場離奇詭異锄开,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)称诗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進(jìn)店門萍悴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事癣诱∪伟叮” “怎么了?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵狡刘,是天一觀的道長。 經(jīng)常有香客問我困鸥,道長嗅蔬,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任疾就,我火速辦了婚禮澜术,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘猬腰。我一直安慰自己鸟废,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布姑荷。 她就那樣靜靜地躺著盒延,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鼠冕。 梳的紋絲不亂的頭發(fā)上添寺,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天,我揣著相機(jī)與錄音懈费,去河邊找鬼计露。 笑死,一個胖子當(dāng)著我的面吹牛憎乙,可吹牛的內(nèi)容都是我干的票罐。 我是一名探鬼主播,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼泞边,長吁一口氣:“原來是場噩夢啊……” “哼该押!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起繁堡,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤沈善,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后椭蹄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體闻牡,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年绳矩,在試婚紗的時候發(fā)現(xiàn)自己被綠了罩润。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡翼馆,死狀恐怖割以,靈堂內(nèi)的尸體忽然破棺而出金度,到底是詐尸還是另有隱情,我是刑警寧澤严沥,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布猜极,位于F島的核電站,受9級特大地震影響消玄,放射性物質(zhì)發(fā)生泄漏跟伏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一翩瓜、第九天 我趴在偏房一處隱蔽的房頂上張望受扳。 院中可真熱鬧,春花似錦兔跌、人聲如沸勘高。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽华望。三九已至,卻和暖如春桦卒,著一層夾襖步出監(jiān)牢的瞬間立美,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工方灾, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留建蹄,地道東北人。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓裕偿,卻偏偏與公主長得像洞慎,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子嘿棘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評論 2 353

推薦閱讀更多精彩內(nèi)容