摘要:保存常量,使其只可讀,實(shí)現(xiàn)方式有哪些語法中的常量聲明符如果聲明一個(gè)對(duì)象會(huì)如何改變?cè)搶?duì)象的屬性聲明的對(duì)象屬性仍然可以改變,因?yàn)閮H僅只是變量指向的那個(gè)內(nèi)存地址不能改動(dòng)。
保存常量,使其只可讀,實(shí)現(xiàn)方式有哪些
1 . es6語法中的常量聲明符 const
const freeze = "strange" freeze = "tony" // => Uncaught TypeError: Assignment to constant variable.
如果const聲明一個(gè)對(duì)象會(huì)如何?
const freezeHero = { name: "strange", skill: "magic" } freezeHero = { name: "no" } // => Uncaught TypeError: Assignment to constant variable. // 改變?cè)搶?duì)象的屬性 freezeHero.name = "tony" freezeHero.skill = "equip" console.log(freezeHero) // => {name: "tony", skill: "equip"}
const聲明的對(duì)象屬性仍然可以改變,因?yàn)閮H僅只是變量指向的那個(gè)內(nèi)存地址不能改動(dòng)。
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"}
可以看到,對(duì)象的靜態(tài)屬性變?yōu)橹蛔x,不可修改,且不可以添加新屬性,如果屬性本身也是對(duì)象會(huì)如何?
const freezeMen = { members: ["tony", "strange"], level: 2 } Object.freeze(freezeMen) freezeMen.level = 4 // 修改對(duì)象的members屬性 Array.prototype.push.apply(freezeMen.members, ["captain", "hulk"]) console.log(freezeMen) // => {members: ["tony", "strange", "captain", "hulk"], level: 2}
被鎖定的對(duì)象,屬性值為簡(jiǎn)單類型時(shí)會(huì)被freeze,但值為對(duì)象時(shí)仍然可以修改,這與const聲明符的原理一致。下面通過遞歸的方式,實(shí)現(xiàn)對(duì)象引用的深層次鎖定,對(duì)象的任何屬性都不可重寫,也不可動(dòng)態(tài)添加新屬性
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方法來增加新屬性,會(huì)直接拋出異常 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
用這個(gè)方法實(shí)現(xiàn)的效果與freeze方法差不多,設(shè)置writable屬性值為只讀,對(duì)于簡(jiǎn)單值類型有效,而屬性值本身為對(duì)象時(shí)仍然是可以修改其值的。同樣可以使用遞歸來實(shí)現(xiàn)
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} // 我們?cè)囋囀褂胐efineProperty添加新屬性 Object.defineProperty(freezeMen, "lastkey", { writable: false, value: "last", enumerable: true }) console.log(freezeMen) // => {add: "new key", members: {people: {name: "default"}, level: 2, lastkey: "last"}
上述方法也可以實(shí)現(xiàn)對(duì)象深層嵌套的屬性凍結(jié),與Object.freeze()的唯一區(qū)別是,傳遞的頂層對(duì)象仍然可以添加新的屬性(不管是通過動(dòng)態(tài)添加還是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()兩種方法的遞歸方案,對(duì)于復(fù)雜的數(shù)據(jù)對(duì)象,可以實(shí)現(xiàn)兩種情況:
1.要存儲(chǔ)一個(gè)完全不可寫的數(shù)據(jù),使用Object.freeze();
2.要存儲(chǔ)一個(gè)不可修改但可拓展的數(shù)據(jù),使用Object.defineProperty()
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/89672.html
摘要:捕抓信息,并且出錯(cuò)時(shí),傳遞給回調(diào)函數(shù)回調(diào)函數(shù)應(yīng)該只調(diào)用一次??偨Y(jié)在學(xué)習(xí)一個(gè)概念或者一個(gè)模塊時(shí),測(cè)試代碼加深你對(duì)知識(shí)的理解和掌握。 一步步打造thunkify 本文的思路: 學(xué)習(xí)thunk相關(guān)知識(shí),主要參考阮一峰的介紹 一步步實(shí)現(xiàn)thunkify模塊,并且使用測(cè)試用例來完善我們的代碼,打造出一個(gè)健壯的模塊 1. 誕生背景 Thunk函數(shù)的誕生是源于一個(gè)編譯器設(shè)計(jì)的問題:求值策略,即函...
摘要:聲明變量常量常量,常量的值非復(fù)合型數(shù)據(jù)不可以改變報(bào)錯(cuò)已聲明為一個(gè)常量,常量一旦聲明只可讀,不允許改變,去修改這個(gè)常量就會(huì)拋出錯(cuò)誤。 const聲明變量(常量): 1、常量,常量的值(非復(fù)合型數(shù)據(jù))不可以改變 const temp = 10; temp = 5;//報(bào)錯(cuò): Assignment to constant variable. //temp已聲明為一個(gè)常量,常量一旦聲明只可讀,...
摘要:關(guān)注我,訂閱專欄基礎(chǔ)語言保姆教學(xué),就可以持續(xù)讀到我的文章啦本文為萬字長(zhǎng)文,滿滿干貨。那么,上面的代碼所運(yùn)行的結(jié)果就是一維數(shù)組的使用使用即可以訪問并可以修改,即可讀可寫。 大家好~~~我是開心學(xué)編程,學(xué)到無極限的@jxwd? 寫在前面: 各位小伙伴還在為C語言的學(xué)習(xí)而苦惱嘛? 還在為...
摘要:所以,拋開這些歧義和陷阱,我的問題變成了標(biāo)簽的位置會(huì)影響首屏?xí)r間么然而答案并不是那么顯而易見,這得從瀏覽器的渲染機(jī)制說起。 說明: 本文提到的瀏覽器均是指Chrome。 script標(biāo)簽指的都是普通的不帶其他屬性的外聯(lián)javascript。 web性能優(yōu)化的手段并不是非黑即白的,有些手段過頭了反而降低性能,所以在討論條件和結(jié)論的時(shí)候,雖然很多條件本身會(huì)帶來其他細(xì)微的負(fù)面或正面影響,為...
閱讀 1621·2019-08-29 13:53
閱讀 3222·2019-08-29 13:50
閱讀 869·2019-08-27 10:51
閱讀 577·2019-08-26 18:36
閱讀 1827·2019-08-26 11:00
閱讀 621·2019-08-26 10:36
閱讀 3229·2019-08-23 17:58
閱讀 2039·2019-08-23 15:17