摘要:保存常量,使其只可讀,實現方式有哪些語法中的常量聲明符如果聲明一個對象會如何改變該對象的屬性聲明的對象屬性仍然可以改變,因為僅僅只是變量指向的那個內存地址不能改動。
保存常量,使其只可讀,實現方式有哪些
1 . es6語法中的常量聲明符 const
const freeze = "strange" freeze = "tony" // => Uncaught TypeError: Assignment to constant variable.
如果const聲明一個對象會如何?
const freezeHero = { name: "strange", skill: "magic" } freezeHero = { name: "no" } // => Uncaught TypeError: Assignment to constant variable. // 改變該對象的屬性 freezeHero.name = "tony" freezeHero.skill = "equip" console.log(freezeHero) // => {name: "tony", skill: "equip"}
const聲明的對象屬性仍然可以改變,因為僅僅只是變量指向的那個內存地址不能改動。
2 . Object.freeze()
Object.freeze()同樣也是es6新增的api
const freezeMan = { name: "tony" } Object.freeze(freezeMan) freezeMan.name = "strange" freezeMan.skill = "magic" console.log(freezeMan) // => {name: "tony"}
可以看到,對象的靜態屬性變為只讀,不可修改,且不可以添加新屬性,如果屬性本身也是對象會如何?
const freezeMen = { members: ["tony", "strange"], level: 2 } Object.freeze(freezeMen) freezeMen.level = 4 // 修改對象的members屬性 Array.prototype.push.apply(freezeMen.members, ["captain", "hulk"]) console.log(freezeMen) // => {members: ["tony", "strange", "captain", "hulk"], level: 2}
被鎖定的對象,屬性值為簡單類型時會被freeze,但值為對象時仍然可以修改,這與const聲明符的原理一致。下面通過遞歸的方式,實現對象引用的深層次鎖定,對象的任何屬性都不可重寫,也不可動態添加新屬性
const freezeMen = { members: ["tony", "strange"], level: 2 } const deepLock = function(obj){ Object.freeze(obj) Object.keys(obj).map((k, i) => { if(typeof obj[k] === "object"){ deepLock(obj[k]) } }) return obj } deepLock(freezeMen).members = ["captian", "hulk"] freezeMen.victory = true console.log(freezeMen) // => {members: ["tony", "strange"], level: 2} // 如果再想通過defineProperty方法來增加新屬性,會直接拋出異常 Object.defineProperty(freezeMen, "lastDefine", { writable: false, value: "it is lastDefine", enumerable: true }) // => Uncaught TypeError: Cannot define property lastDefine, object is not extensible
3 . Object.defineProperty
用這個方法實現的效果與freeze方法差不多,設置writable屬性值為只讀,對于簡單值類型有效,而屬性值本身為對象時仍然是可以修改其值的。同樣可以使用遞歸來實現
var lockProperty = function(data) { if(typeof data === "object") { Object.keys(data).map(key => { defineDisWritable(data, key, data[key]) }) } return data } var defineDisWritable = function(obj, key, val) { Object.defineProperty(obj, key, { writable: false, value: val, enumerable: true }) if(typeof val === "object") { lockProperty(val) } } const freezeMen = { members: { people: { name: "default" } }, level: 2 } lockProperty(freezeMen) freezeMen.add = "new key" freezeMen.level = 10 freezeMen.members = { house: "big" } freezeMen.members.people.name = "modified" console.log(freezeMen) // => {add: "new key", members: {people: {name: "default"}, level: 2} // 我們試試使用defineProperty添加新屬性 Object.defineProperty(freezeMen, "lastkey", { writable: false, value: "last", enumerable: true }) console.log(freezeMen) // => {add: "new key", members: {people: {name: "default"}, level: 2, lastkey: "last"}
上述方法也可以實現對象深層嵌套的屬性凍結,與Object.freeze()的唯一區別是,傳遞的頂層對象仍然可以添加新的屬性(不管是通過動態添加還是Object.defineProperty)。
還可以通過劫持setter來鎖定通過defineProperty方法添加的屬性。
var lockProperty = function(data) { if(typeof data === "object") { Object.keys(data).map(key => { defineDisWritable(data, key, data[key]) }) } return data } var defineDisWritable = function(obj, key, val) { Object.defineProperty(obj, key, { set: function(newVal) { // 不賦新值 // val = newVal }, get: function() { return val }, enumerable: true }) if(typeof val === "object") { lockProperty(val) } } const freezeMen = { members: { people: { name: "default" } }, level: 2 } lockProperty(freezeMen) freezeMen.add = "new key" freezeMen.level = 10 freezeMen.members = { house: "big" } freezeMen.members.people.name = "modified" console.log(freezeMen) // => {add: "new key", members: {people: {name: "default"}, level: 2}
_比較Object.defineProperty()和Object.freeze()兩種方法的遞歸方案,對于復雜的數據對象,可以實現兩種情況:
1.要存儲一個完全不可寫的數據,使用Object.freeze();
2.要存儲一個不可修改但可拓展的數據,使用Object.defineProperty()
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/89672.html
摘要:聲明變量常量常量,常量的值非復合型數據不可以改變報錯已聲明為一個常量,常量一旦聲明只可讀,不允許改變,去修改這個常量就會拋出錯誤。 const聲明變量(常量): 1、常量,常量的值(非復合型數據)不可以改變 const temp = 10; temp = 5;//報錯: Assignment to constant variable. //temp已聲明為一個常量,常量一旦聲明只可讀,...
摘要:關注我,訂閱專欄基礎語言保姆教學,就可以持續讀到我的文章啦本文為萬字長文,滿滿干貨。那么,上面的代碼所運行的結果就是一維數組的使用使用即可以訪問并可以修改,即可讀可寫。 大家好~~~我是開心學編程,學到無極限的@jxwd? 寫在前面: 各位小伙伴還在為C語言的學習而苦惱嘛? 還在為...
摘要:所以,拋開這些歧義和陷阱,我的問題變成了標簽的位置會影響首屏時間么然而答案并不是那么顯而易見,這得從瀏覽器的渲染機制說起。 說明: 本文提到的瀏覽器均是指Chrome。 script標簽指的都是普通的不帶其他屬性的外聯javascript。 web性能優化的手段并不是非黑即白的,有些手段過頭了反而降低性能,所以在討論條件和結論的時候,雖然很多條件本身會帶來其他細微的負面或正面影響,為...
閱讀 1612·2019-08-29 13:53
閱讀 3211·2019-08-29 13:50
閱讀 855·2019-08-27 10:51
閱讀 567·2019-08-26 18:36
閱讀 1798·2019-08-26 11:00
閱讀 605·2019-08-26 10:36
閱讀 3218·2019-08-23 17:58
閱讀 2033·2019-08-23 15:17