ES6 系列十一:對象的拓展

"Code tailor",爲前端開發者提供技術相關資訊以及系列基礎文章,微信關注「小和山的菜鳥們」公衆號,及時獲取最新文章。

前言

在開始學習以前,咱們想要告訴您的是,本文章是對阮一峯《ECMAScript6 入門》一書中 "對象的擴展" 章節的總結,若是您已掌握下面知識事項,則可跳過此環節直接進入題目練習javascript

  • 對象如何簡潔表達 ?
  • 屬性遍歷的方法有哪些 ?
  • 什麼是 super 運算符 ?
  • 對象擴展運算符有哪些做用 ?

若是您對某些部分有些遺忘,👇🏻 已經爲您準備好了!前端

學習連接

對象的擴展學習java

彙總總結

對象的簡潔表達

ES6 容許在大括號裏面,直接寫入變量和函數,做爲對象的屬性和方法
let birth = '1999/01/01'

const Person = {
  name: '李四',

  //等同於birth: birth
  birth,

  // 等同於hello: function ()...
  hello() {
    console.log('個人名字是', this.name)
  },
}

屬性遍歷

  • for...in: 循環遍歷對象自身的和繼承的可枚舉屬性(不含 Symbol 屬性)。
  • Object.keys(obj): 返回一個數組,包括對象自身的(不含繼承的)全部可枚舉屬性(不含 Symbol 屬性)的鍵名。
  • Object.getOwnPropertyNames(obj): 返回一個數組,包含對象自身的全部屬性(不含 Symbol 屬性,可是包括不可枚舉屬性)的鍵名。
  • Object.getOwnPropertySymbols(obj): 返回一個數組,包含對象自身的全部 Symbol 屬性的鍵名。
  • Reflect.ownKeys(obj): 返回一個數組,包含對象自身的(不含繼承的)全部鍵名,無論鍵名是 Symbol 或字符串,也無論是否可枚舉。

以上的 5 種方法遍歷對象的鍵名,都遵照一樣的屬性遍歷的次序規則。es6

  • 首先遍歷全部數值鍵,按照數值升序排列。
  • 其次遍歷全部字符串鍵,按照加入時間升序排列。
  • 最後遍歷全部 Symbol 鍵,按照加入時間升序排列。

super 運算符

指向當前對象的原型對象
const proto = {
  foo: 'hello',
}

const obj = {
  foo: 'world',
  find() {
    return super.foo
  },
}

Object.setPrototypeOf(obj, proto)
obj.find() // "hello"

//上面代碼中,對象obj.find()方法之中,經過super.foo引用了原型對象proto的foo屬性。

注意,super 關鍵字表示原型對象時,只能用在對象的方法之中,用在其餘地方都會報錯。數組

對象擴展運算符

1. 解構賦值微信

對象的解構賦值用於從一個對象取值,至關於將目標對象自身的全部可遍歷的( enumerable )、但還沒有被讀取的屬性,分配到指定的對象上面。全部的鍵和它們的值,都會拷貝到新對象上面。
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 }
x // 1
y // 2
z // { a: 3, b: 4 }

//變量z是解構賦值所在的對象。它獲取等號右邊的全部還沒有讀取的鍵(a和b)
//將它們連同值一塊兒拷貝過來。

注意: 函數

  • 解構賦值要求等號右邊是一個對象,因此若是等號右邊是 undefinednull ,就會報錯,由於它們沒法轉爲對象。
  • 解構賦值必須是最後一個參數,不然會報錯。
  • 解構賦值的拷貝是淺拷貝,即若是一個鍵的值是複合類型的值(數組、對象、函數)、那麼解構賦值拷貝的是這個值的引用,而不是這個值的副本。
let obj = { a: { b: 1 } }
let { ...x } = obj
obj.a.b = 2
x.a.b // 2
  • 擴展運算符的解構賦值,不能複製繼承自原型對象的屬性

1. 擴展運算符學習

取出參數對象的全部可遍歷屬性,拷貝到當前對象之中。
let z = { a: 3, b: 4 }
let n = { ...z }
n // { a: 3, b: 4 }

注意: this

  • 對象的擴展運算符也能夠用於數組。
let foo = { ...['a', 'b', 'c'] }
foo
// {0: "a", 1: "b", 2: "c"}
  • 若是擴展運算符後面是一個空對象,則沒有任何效果。
{...{}, a: 1}
// { a: 1 }
  • 若是擴展運算符後面不是對象,則會自動將其轉爲對象。
// 等同於 {...Object(1)}
{...1} // {}
  • 對象的擴展運算符等同於使用 Object.assign() 方法。
let aClone = { ...a }
// 等同於
let aClone = Object.assign({}, a)

題目自測

一: 使用擴展運算符,進行深拷貝,將 obj1 的內容拷貝到 obj2 中(不考慮對象嵌套的問題).code


二: 如下哪一種方式爲不正確的定義字面量對象的方法?

A.

var obj = {
  foo: true,
  abc: 123,
}

B.

let propKey = 'foo'

let obj = {
  [propKey]: true,
  ['a' + 'bc']: 123,
}

C.

const foo = 'bar'
const baz = { [foo]: 'abc' }

D.

const foo = 'bar';
const bar = 'abc';
const baz = { [foo] };

三: 如下三個對象使用擴展運算符進行拼接,輸出結果是什麼?

let obj1 = { name: 'hzq', age: 18 }
let obj2 = { name: 'yry', age: 19 }
let obj3 = { name: 'ljj', age: 20, role: 'boss' }
let obj4 = { ...obj1, ...obj2, ...obj3 }
console.log(obj4) // {name: 'ljj', age: 20, role: 'boss'}

題目解析

1、

Answer:

let obj1 = { name: 'hzq', age: 18 }
let obj2 = { ...obj1 }

對象中的擴展運算符(...)用於取出參數對象中的全部可遍歷屬性,拷貝到當前對象之中

2、

Answer:D

A 選項爲標準的 ES5 定義字面量對象的方法。B 選項爲 ES6 中,在大括號中,容許使用表達式做爲對象屬性名。C 選項如同 B 選項。D 選項的錯誤在於,屬性名錶達式與簡潔表示法沒法同時使用。

3、

Answer:

擴展運算符的使用將obj1,obj2,obj3三個變成{name: 'hzq', age: 18, name: 'yry', age:19, name: 'ljj', age:20, role:'boss'}

這裏有一個注意點就是:若是是對象的拼接,對於同一個 key 的鍵值對,後面的會覆蓋前面的

因此最終結果變就是{name: 'ljj', age:20, role:'boss'}

相關文章
相關標籤/搜索