面試官:請你介紹一下let const Object.freeze() set和get

前端巔峯 每日一題 :

第一季:ES6基礎系列:html

思考題:前端

let , const , object.freeze() 的區別vue

從最簡單的const開始:git

按上面這樣寫 會報錯程序員

提示:github

Assignment to constant variable.vuex

賦值給了常量數組

可是當咱們:bash

發現代碼正常運行,沒有報任何錯前端框架

那麼我再試一下對象

發現一切運行正常

接下來嘗試let:

發現代碼運行正常無報錯

咱們翻看阮一峯老師的ES6入門:

const:

let:

const實際上保證的,並非變量的值不得改動,而是變量指向的那個內存地址所保存的數據不得改動。

對於簡單類型的數據(數值、字符串、布爾值),值就保存在變量指向的那個內存地址,所以等同於常量。

但對於複合類型的數據(主要是對象和數組),變量指向的內存地址,保存的只是一個指向實際數據的指針,const只能保證這個指針是固定的(即老是指向另外一個固定的地址),至於它指向的數據結構是否是可變的,就徹底不能控制了。

總結來講:const 並不能真正意義上保證 ‘不變’

ES5的淺凍結,使用API Object.freeze()

正常狀況下,下面這段代碼:

最終輸出:

{a: "a", b: {…}}

a的值是被改變了 但是打開註釋的代碼 Object.freeze(obj)

最終輸出:

{a: 1, b: {…}}

此時a的值並無被改變,由於它被「凍結」了

上面有提到淺凍結,那麼看看修改b的值會不會有效果:

最終輸出以下:

{a: 1, b: {…}}
a: 1
b: {c: 2}

複製代碼

證實b也被凍結了

再次嘗試修改C的值:

輸出:

{a: 1, b: {…}}
a: 1
b: {c: 2}

複製代碼

看來Object.freeze()也不能徹底凍結,可是萬能的程序員小哥哥是不可能屈服的,簡單粗暴的遞歸,深凍結 :

這時候咱們修改了c的值:

發現輸出:

{a: 1, b: {…}}
a: 1
b: {c: 2}
複製代碼

看來此次是真的凍住了,不過深凍結也要根據數據的類型判斷進行凍結,不然就不能真正意義上的徹底凍結。

vue 1.0.18+Object.freeze()提供了支持,對於datavuex裏使用freeze凍結了的對象,vue不會作gettersetter的轉換。

若是你有一個巨大的數組或Object,而且確信數據不會修改,使用Object.freeze()可讓性能大幅提高。

Object.freeze() 方法能夠凍結一個對象。一個被凍結的對象不再能被修改;凍結了一個對象則不能向這個對象添加新的屬性,不能刪除已有屬性,不能修改該對象已有屬性的可枚舉性、可配置性、可寫性,以及不能修改已有屬性的值。此外,凍結一個對象後該對象的原型也不能被修改。

但它凍結的是值,你仍然能夠將變量的引用替換掉

上面提到的:

可枚舉性、可配置性、可寫性,以及不能修改已有屬性的值

上面經過Object.defineProperty()定義的屬性,訪問獲得打印輸出2

下面對三個屬性描述符進行解析:

writable:決定是否能夠修改屬性的值

打印輸出仍是2 ,屬性a的值不能被改變

解析:writable:false 能夠看做爲屬性不可改變,在嚴格模式("use strict";)下,引擎會拋出TypeError的異常,這表示咱們沒法修改一個不可寫的屬性

configurable:只要屬性是可配置的,就可使用 defineProperty(...)方法來修改屬性描述符

注意⚠️

false狀況下,若是修改,不論是不是嚴格模式,都會拋出TypeError的錯誤

在這種狀況下,咱們仍能夠將可寫性的狀態由true改成false

delete屬性也會被禁止(delete myObject.a;)

emumerable:可枚舉,若是將它設置爲false,則這個屬性將不會出如今枚舉中,但能夠正常訪問他

屬性描述符上面有介紹,最後介紹下訪問描述符

定義對象時,加入訪問描述符:

正常狀況下,訪問 p.age 輸出18

可是設置p.age=101後:

就會拋出錯誤

index.html:65 Uncaught Error: invalid value
    at Object.set age [as age] (index.html:65)
    at index.html:71

複製代碼

訪問描述符的做用:

get : 每次獲取屬性時候調用 例如 console.log(p.age) 這時候會調用get

set : 每次設置屬性的時候調用 例如 p.age = 101 他們兩個甚至能夠徹底無關

特別提示 ,它們兩個的調用邏輯必定要捋清楚,耦合度過高容易進入死循環

著名的Vue框架在2.x版本就藉此實現的響應式~

例如 :

只須要通知全部訂閱這個數據改變的組件進行更新,而且傳遞新的值~

上面只是僞代碼,可是大體思想如此

若是感受寫得不錯,歡迎點個在看,推薦到朋友圈

另外開源項目 Palantir 目前已經接入微前端,微前端框架正在編寫中~

倉庫地址:

https://github.com/JinJieTan/Palantir
複製代碼

Palantir倉庫地址

歡迎加入~ 咱們的大羣體,以及交流羣,公衆號回覆:加羣

便可加羣

相關文章
相關標籤/搜索