除了普通的物件屬性賦值和遍歷之外,我們還可以使用 JavaScript 物件執行許多其他操作。在本文中,我們將了解如何使用它們,包括存取內部屬性、操作屬性描述符和繼承唯讀屬性。
1. 存取內部屬性
JavaScript 物件無法以常規方式存取的內部屬性。內部屬性名稱由雙方括號[[]]包圍,在建立物件時可用。
內部屬性不能動態地加入到現有物件。
內部屬性可以在某些內建 JavaScript 物件中使用,它們儲存ECMAScript規範指定的內部狀態。
有兩種內部屬性,一種操作物件的方法,另一種是儲存資料的方法。例如:
[[Prototype]] — 物件的原型,可以為null或物件
[[Extensible]] — 表示是否允許在物件中動態新增新的屬性
[[PrivateFieldValues]] — 用於管理私有類別欄位
let foo = { a: 1}那麼,a 的value屬性描述子為1。 writable是指該屬性的值是否可以變更。預設值為true,表示屬性是可寫入的。但是,我們可以透過多種方式將其設為不可寫入。 configurable 的意思是可以刪除物件的屬性還是可以變更其屬性描述符。預設值為true,這表示它是可配置的。 enumerable 意味著它可以被for ... in迴圈遍歷。預設值為true,說明能透過for-in循環傳回屬性將屬性鍵加入傳回的陣列之前,Object.keys方法也檢查enumerable 描述符。但是,Reflect.ownKeys方法不會檢查此屬性描述符,而是傳回所有自己的屬性鍵。 Prototype描述子有其他方法,get和set分別用來取得和設定值。 在建立新對象, 我們可以使用Object.defineProperty方法設定的描述符,如下所示:
let foo = { a: 1}Object.defineProperty(foo, 'b', { value: 2, writable: true, enumerable: true, configurable: true,});這樣得到foo的新值是{a: 1, b: 2} 。
我們也可以使用defineProperty來變更現有屬性的描述符。例如:
let foo = { a: 1}Object.defineProperty(foo, 'a', { value: 2, writable: false, enumerable: true, configurable: true,});這樣當我們嘗試給 foo.a 賦值時,如:
foo.a = 2;如果關閉了嚴格模式,瀏覽器將忽略,否則將拋出一個錯誤,因為我們將writable 設定為false, 表示該屬性不可寫。
我們也可以使用defineProperty將屬性轉換為getter,如下所示:
'use strict'let foo = { a: 1}Object.defineProperty(foo, 'b', { get() { return 1; } })當我們這樣寫的時候:
foo.b = 2;因為b屬性是getter屬性,所以當使用嚴格模式時,我們會得到一個錯誤:Getter 屬性不能重新賦值。 3.無法指派繼承的唯讀屬性
const proto = Object.defineProperties({}, { a: { value: 1, writable: false }})const foo = Object.create(proto)在上面的程式碼中,我們將proto.a的 writable 描述子設為false,因此我們無法為其指派其他值。 如果我們這樣寫:
foo.a = 2;在嚴格模式下,我們會收到錯誤訊息。
總結
我們可以用 JavaScript 物件做很多我們可能不知道的事情。
首先,某些 JavaScript 物件(例如內建瀏覽器物件)具有內部屬性,這些屬性由雙方括號包圍,它們具有內部狀態,物件建立無法動態新增。 JavaScript物件屬性還具有屬性描述符,該屬性描述符使我們可以控制其值以及可以設定它們的值,還是可以更改其屬性描述符等。 我們可以使用defineProperty來變更屬性的屬性描述符,它也用於新增屬性及其屬性描述符。最後,繼承的唯讀屬性保持只讀狀態,這是有道理的,因為它是從父原型物件繼承而來的。
推薦教學: 《javascript教學》
以上是JavaScript 物件可以做到的幾件事的詳細內容。更多資訊請關注PHP中文網其他相關文章!