第一季: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()
提供了支持,對於data
或vuex
裏使用freeze
凍結了的對象,vue
不會作getter
和setter
的轉換。
若是你有一個巨大的數組或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
倉庫地址
歡迎加入~ 咱們的大羣體,以及交流羣,公衆號回覆:加羣
便可加羣