成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

js保存常量,使其只可讀,實(shí)現(xiàn)方式有哪些

liuhh / 3123人閱讀

摘要:保存常量,使其只可讀,實(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

相關(guān)文章

  • Thunk深入解析

    摘要:捕抓信息,并且出錯(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ì)的問題:求值策略,即函...

    xi4oh4o 評(píng)論0 收藏0
  • 關(guān)于const的聲明

    摘要:聲明變量常量常量,常量的值非復(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è)常量,常量一旦聲明只可讀,...

    Profeel 評(píng)論0 收藏0
  • 0基礎(chǔ)C語言保姆教學(xué)——第五節(jié) 數(shù)組

    摘要:關(guān)注我,訂閱專欄基礎(chǔ)語言保姆教學(xué),就可以持續(xù)讀到我的文章啦本文為萬字長(zhǎng)文,滿滿干貨。那么,上面的代碼所運(yùn)行的結(jié)果就是一維數(shù)組的使用使用即可以訪問并可以修改,即可讀可寫。 大家好~~~我是開心學(xué)編程,學(xué)到無極限的@jxwd? 寫在前面: 各位小伙伴還在為C語言的學(xué)習(xí)而苦惱嘛? 還在為...

    RobinQu 評(píng)論0 收藏0
  • PHP Q&A

    摘要:有哪些作用域函數(shù)作用域類作用域函數(shù)作用域是什么函數(shù)體是一個(gè)局部作用域函數(shù)體中無法直接訪問外部全局變量,必須通過才能訪問外部全局變量無法訪問通知錯(cuò)誤正確訪問外部全局變量無法訪問函數(shù)體中可以直接訪問常量輸出函數(shù)體中可以直接訪問類靜態(tài)屬性靜態(tài)方法 PHP 有哪些作用域? 函數(shù)作用域 類作用域 PHP 函數(shù)作用域是什么? 函數(shù)體是一個(gè)局部作用域 函數(shù)體中無法直接訪問外部全局變量,必須通...

    mikasa 評(píng)論0 收藏0
  • JS 一定要放在 Body 的最底部么?聊聊瀏覽器的渲染機(jī)制

    摘要:所以,拋開這些歧義和陷阱,我的問題變成了標(biāo)簽的位置會(huì)影響首屏?xí)r間么然而答案并不是那么顯而易見,這得從瀏覽器的渲染機(jī)制說起。 說明: 本文提到的瀏覽器均是指Chrome。 script標(biāo)簽指的都是普通的不帶其他屬性的外聯(lián)javascript。 web性能優(yōu)化的手段并不是非黑即白的,有些手段過頭了反而降低性能,所以在討論條件和結(jié)論的時(shí)候,雖然很多條件本身會(huì)帶來其他細(xì)微的負(fù)面或正面影響,為...

    VincentFF 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

liuhh

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<