JavaScript 對象能夠作到的三件事

做者:John Au-Yeung
譯者:前端小智
來源:medium
點贊再看,養成習慣

本文 GitHub https://github.com/qq44924588... 上已經收錄,更多往期高贊文章的分類,也整理了不少個人文檔,和教程資料。歡迎Star和完善,你們面試能夠參照考點複習,但願咱們一塊兒有點東西。前端

除了普通的對象屬性賦值和遍歷以外,咱們還可使用 JavaScript 對象執行許多其餘操做。在本文中,咱們將瞭解如何使用它們,包括訪問內部屬性、操做屬性描述符和繼承只讀屬性。git

1. 訪問內部屬性

JavaScript 對象沒法以常規方式訪問的內部屬性內部屬性名由雙方括號[[]]包圍,在建立對象時可用。github

內部屬性不能動態地添加到現有對象。面試

內部屬性能夠在某些內置 JavaScript 對象中使用,它們存儲ECMAScript規範指定的內部狀態。數組

有兩種內部屬性,一種操做對象的方法,另外一種是存儲數據的方法。例如:瀏覽器

  • [[Prototype]] — 對象的原型,能夠爲null或對象
  • [[Extensible]] — 表示是否容許在對象中動態添加新的屬性
  • [[PrivateFieldValues]] — 用於管理私有類字段

2. 屬性描述符對象

數據屬性包含了一個數據值的位置,在這個位置能夠讀取和寫入值。也就是說,數據屬性能夠經過 對象.屬性 訪問,就是我麼日常接觸的用戶賦什麼值,它們就返回什麼,不會作額外的事情。微信

數據屬性有4個描述其行爲的特性(爲了表示內部值,把屬性放在兩對方括號中),稱爲描述符對象工具

屬性 解釋 默認值
[[Configurable]] 可否經過delete刪除屬性從而從新定義屬性;
可否修改屬性的特性;
可否把屬性修改成訪問器屬性
true
[[Enumerable]] 可否經過for-in循環返回屬性 true
[[Writable]] 可否修改屬性的值 true
[[Value]] 包含這個屬性的數據值 undefined

value 描述符是屬性的數據值,例如,咱們有如下對象 :this

let foo = {
  a: 1
}

那麼,avalue屬性描述符爲1spa

writable是指該屬性的值是否能夠更改。 默認值爲true,表示屬性是可寫的。 可是,咱們能夠經過多種方式將其設置爲不可寫。

configurable 的意思是能夠刪除對象的屬性仍是能夠更改其屬性描述符。 默認值爲true,這意味着它是可配置的。

enumerable 意味着它能夠被for ... in循環遍歷。 默認值爲true,說明能經過for-in循環返回屬性

將屬性鍵添加到返回的數組以前,Object.keys方法還檢查enumerable 描述符。 可是,Reflect.ownKeys方法不會檢查此屬性描述符,而是返回全部本身的屬性鍵。

Prototype描述符有其餘方法,getset分別用於獲取和設置值。

在建立新對象, 咱們可使用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.沒法分配繼承的只讀屬性

繼承的只讀屬性不能再賦值。這是有道理的,由於咱們這樣設置它,它是繼承的,因此它應該傳播到繼承屬性的對象。

咱們可使用Object.create建立一個從原型對象繼承屬性的對象,以下所示:

const proto = Object.defineProperties({}, {
  a: {
    value: 1,
    writable: false
  }
})

const foo = Object.create(proto)

在上面的代碼中,咱們將proto.awritable 描述符設置爲false,所以咱們沒法爲其分配其餘值。

若是咱們這樣寫:

foo.a = 2;

在嚴格模式下,咱們會收到錯誤消息。

總結

咱們能夠用 JavaScript 對象作不少咱們可能不知道的事情。

首先,某些 JavaScript 對象(例如內置瀏覽器對象)具備內部屬性,這些屬性由雙方括號包圍,它們具備內部狀態,對象建立沒法動態添加。

JavaScript對象屬性還具備屬性描述符,該屬性描述符使咱們能夠控制其值以及能夠設置它們的值,仍是能夠更改其屬性描述符等。

咱們可使用defineProperty更改屬性的屬性描述符,它還用於添加新屬性及其屬性描述符。

最後,繼承的只讀屬性保持只讀狀態,這是有道理的,由於它是從父原型對象繼承而來的。


代碼部署後可能存在的BUG無法實時知道,過後爲了解決這些BUG,花了大量的時間進行log 調試,這邊順便給你們推薦一個好用的BUG監控工具 Fundebug

原文:https://medium.com/@amesimmon...


交流

文章每週持續更新,能夠微信搜索「 大遷世界 」第一時間閱讀和催更(比博客早一到兩篇喲),本文 GitHub https://github.com/qq449245884/xiaozhi 已經收錄,整理了不少個人文檔,歡迎Star和完善,你們面試能夠參照考點複習,另外關注公衆號,後臺回覆福利,便可看到福利,你懂的。

相關文章
相關標籤/搜索