如何在 ES5 環境下實現一個const ?

轉自如何在 ES5 環境下實現一個const ?

個人GitHub地址:Githubgit

前言

  • 剛剛看了掘金上一篇文章《做爲技術面試官,爲何把你pass了》,裏面第一題就是用es5實現const,據做者反饋 這一題全部的面試者都沒有回答出來,感受挺惋惜的,其實這是一道比較簡單的題目,可是因爲涉及到了一些Object對象屬性描述符的知識,這些描述符每每用到的場景很少,因此不容易記住。

屬性描述符:

對象裏目前的屬性描述符有兩種:

  • 數據描述符:具備值的屬性
  • 存取描述符:由getter與setter函數對描述的屬性

描述符功能:

數據描述符與存取描述符皆可修改:

  • configurable:當前對象元素的屬性描述符是否可改,是否可刪除
  • enumerable:當前對象元素是否可枚舉

惟有數據描述符能夠修改:

  • value: 當前對象元素的值
  • writable:當前對象元素的值是否可修改

惟有存取描述符能夠修改:

  • get:讀取元素屬性值時的操做
  • set:修改元素屬性值時的操做

描述符可同時具備的鍵值:

configurable enumerable value writable get set
數據描述符 Yes Yes Yes Yes No No
存取描述符 Yes Yes No No Yes Yes

const 實現原理

因爲ES5環境沒有block的概念,因此是沒法百分百實現const,只能是掛載到某個對象下,要麼是全局的window,要麼就是自定義一個object來當容器github

var __const = function __const (data, value) {
        window.data = value // 把要定義的data掛載到window下,並賦值value
        Object.defineProperty(window, data, { // 利用Object.defineProperty的能力劫持當前對象,並修改其屬性描述符
          enumerable: false,
          configurable: false,
          get: function () {
            return value
          },
          set: function (data) {
            if (data !== value) { // 當要對當前屬性進行賦值時,則拋出錯誤!
              throw new TypeError('Assignment to constant variable.')
            } else {
              return value
            }
          }
        })
      }
      __const('a', 10)
      console.log(a)
      delete a
      console.log(a)
      for (let item in window) { // 由於const定義的屬性在global下也是不存在的,因此用到了enumerable: false來模擬這一功能
        if (item === 'a') { // 由於不可枚舉,因此不執行
          console.log(window[item])
        }
      }
      a = 20 // 報錯
複製代碼複製代碼

題外話

Vue目前雙向綁定的核心實現思路就是利用Object.defineProperty對getset進行劫持,監聽用戶對屬性進行調用以及賦值時的具體狀況,從而實現的雙向綁定~~面試

相關文章
相關標籤/搜索