JavaScript總結系列之對象

對象

我們都知道,對象一般是類的實例,如 Java,Python 等這類面嚮對象語言,而 JavaScript 中沒有類,因此 JavaScript 中的對象不是類的實例,而是基於原型的對象。
JavaScript 中的對象 Object 是 7 種內置類型(number, string, null, undefined, boolean, object, symbol)之一,是由 key 和 value 組成,value 可以是任意數據類型。

🔨 創建

JavaScript 可以用 聲明形式構造形式 的方式創建對象

聲明形式

let obj = {
  name: 'Jon',
  age: 18,
  say: () => {
    console.log('hello')
  }
}

這種方式創建的對象需要注意點是,按照命名規範命名的 key 加不加引號都可以,不符合命名規範的 key 要加引號,如:

let obj = {
  'first_name': 'Jon',
}

構造形式

let obj = new Object()
obj.name = 'Jon'
obj.age = 18
obj.say = () => {
  console.log('hello')
}

給構造器生成的對象添加屬性需要一個一個添加

🔦 訪問

訪問一個對象的屬性值可以通過 .操作符[]操作符 進行訪問,舉個粟子:

.操作符:要求屬性名滿足標識符的命名規範

[]操作符:可以接受任意 UTF-8/Unicode 字符串作爲屬性名

let obj = {
  'first_name': 'Jon',
  age: 18,
  say: () => {
    console.log('hello')
  }
}

obj.age // 通過 .運算符 訪問,18
obj['age'] // 通過 []操作符  訪問,18
obj['first_name'] // 通過 []操作符 訪問,Jon

🔧 get/set

使用 get

let person = {
  _age: 18,
  get age () {
    return this._age
  }
}

person.age // Jon's age: 18

使用 set

let play = {
  game: [],
  set current (name) {
    this.game.push(name)
  }
}

play.current = 'dota2'
play.game // ['dota2']

涉及 getter 和 setter 的 Object.create()、object.defineProperty()、object.defineProperties() 後待補充

🔥 對象的擴展(ES6 / ES7)

🌖 屬性簡寫

let name = 'Jon'
let persion = {name}
// 等同於
let persion = {name: name}

🌗 對象函數簡寫

let persion = {
  say () {
    console.log('hello')
  }
}
// 等同於
let persion = {
  say: function () {
    console.log('hello')
  }
}

🌒 屬性表達式

屬性,方法名,getter 和 setter 都支持

let firstname = 'first name'
let age = 'age'
let current = 'current'
let person = {
  [firstname] : 'Jon',
  get [age] () {
    return 18
  },
  set [current] (name) {
    this[firstname] = name
  }
}
person['first name'] // 'Jon'
person.age // 18
person.current = 'karon'
person['first name'] // 'karon'

注意:屬性表達式和簡寫不能同時使用,比如:

let firstname = 'first name'
// 報錯
let persion = {
  [firstname]
}

🌘 屬性的遍歷

ES6 一共有 5 種方法可以遍歷對象的屬性。

  1. for...in 循環遍歷對象自身的和繼承的可枚舉屬性(不含 Symbol 屬性)。
  2. Object.keys(obj) 返回一個數組,包括對象自身的(不含繼承的)所有可枚舉屬性(不含 Symbol 屬性)的鍵名。
  3. Object.getOwnPropertyNames(obj) 返回一個數組,包含對象自身的所有屬性(不含 Symbol 屬性,但是包括不可枚舉屬性)的鍵名。
  4. Object.getOwnPropertySymbols(obj) 返回一個數組,包含對象自身的所有 Symbol 屬性的鍵名。
  5. Reflect.ownKeys(obj) 返回一個數組,包含對象自身的所有鍵名,不管鍵名是 Symbol 或字符串,也不管是否可枚舉。

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

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

🌔 對象解構、擴展運算符

let person = {
  name: 'Jon',
  age: 18,
  say () {
    console.log('hello')
  }
}

let {name, age, say} = person

要求等號右邊必須是一個對象,否則會報錯,如:

let {a} = undefined // 報錯
let {a} = null // 報錯

並沒有拷貝到原型對象上的屬性

let name = {name: 'Jon'}
let person = {age: 18}
person.__proto__ = name
let {...a} = person
a.name // undefined

如果屬性對象,只是拷貝引用

let person = { habit: {name: 'play game' }}
let {...a} = person
person.habit.name = 'study'
a.habit.name // study

展開

let obj = {
  name: 'Jon',
  age: 18
}

let person = {...obj}
person // { name: 'Jon', age: 18 }

利用展開可以用來合併對象

let gift = { skill: 'faster' }
let person = {
  name: 'barry'
}
let flash = {...person, ...gift}
flash // {name: 'barry', skill: 'faster'}

🌕 新增的常用方法

  • 【es6】Object.is(..)

比較兩個值是否相同,與 === 嚴格比較的區別在 +0 與-0,NaN 與 NaN

+0 === -0 // true
NaN === NaN // false
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
  • 【es6】Object.assign(..)

對象合併,將後面的對象的屬性複製給第一個參數,也就是目標對象,需注意:可複製的屬性爲自身屬性和可枚舉的屬性,繼承而來的屬性無法被複制,如果是相同屬性,後面的會覆蓋前面的,舉個栗子:

let person = { name: 'barry', skill: 'run' }
let superSkill = {skill: 'flash'}
Object.assign({}, person, superSkill) // {name: 'barry', skill: 'flash'}

也可以用來處理數組,如下,b 把 a 引索爲 0 和 1 的覆蓋了

let a = [1, 2, 3]
let b = [4, 5]
Object.assign([], a, b) // [4, 5, 3]
  • 【es6】Object.keys(..)

遍歷自身屬性,不含繼承屬性和 Symbol 屬性

let person = { name: 'barry', skill: 'run', [Symbol('skill')]: 'run flash'}
Object.keys(person) // ['name', 'skill']
  • 【es6】Object.getOwnPropertySymbols(..)
let person = {
  [Symbol('skill')]: 'run flash'
}

Object.getOwnPropertySymbols(person) // [Symbol(skill)]
  • 【es7】Object.values(..)

遍歷自身屬性,不含繼承屬性和 Symbol 屬性

let person = { name: 'barry', skill: 'run', [Symbol('skill')]: 'run flash'}
Object.values(person) // ['barry', 'run']
  • 【es7】Object.entries(..)

遍歷自身屬性,不含繼承屬性和 Symbol 屬性

let person = { name: 'barry', skill: 'run', [Symbol('skill')]: 'run flash'}
Object.entries(person) // [['name', 'barry'], ['skill', 'run']]

將對象轉爲 Map 對象:

let person = { name: 'barry', skill: 'run', [Symbol('skill')]: 'run flash'}
let personArr = Object.entries(person) // [['name', 'barry'], ['skill', 'run']]
let personMap = new Map(personArr) // Map { name: 'barry', skill: 'run' }
  • 【es7】Object.fromEntries(..)

爲 Object.entries()的逆操作,用於將一個鍵值對數組轉爲對象。

let person = [['name', 'barry'], ['skill', 'run']]
Object.fromEntries(person) // { name: 'barry', skill: 'run' }
  • 【es7】Object.getOwnPropertyDescriptors(..)
    獲取對象所有自身的屬性描述符
let barry = { name: 'barry', skill: 'run' }
Object.getOwnPropertyDescriptors(barry)
/* {
  name: {
    value: "barry",
    configurable: true,
    enumerable: true,
    writable: true
  },
  skill: {
    value: "run",
    configurable: true,
    enumerable: true,
    writable: true
  }
} */

對應的有:【ES5】的 Object.getOwnPropertyDescriptor(..)

❄️ 總結自:


前端總結小本本更新時間爲:週二,週四,週六,內容不定
如想查看最新未完成總結,可請查看:https://github.com/KaronAmI/blog
如有啓發,歡迎 star,如有錯誤,請務必指出,十分感謝。🌹

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章