JavaScript中對象的不變性

屬性描述符

ES5開始所有的屬性都有了屬性描述符,以表示屬性的一些特性佩微。
我們可以通過Object.getOwnPropertyDescriptor(...)查看屬性描述符。

let obj = {a: 'a'};
let descriptor = Object.getOwnPropertyDesciptor(obj, 'a');
//descriptor: {value: 'a', writable: true, enumerable: true, configurable: true}

這里我們只討論其中的writable(可寫)萌焰、configurable(可配置)哺眯,我們可以通過Object.defineProperety(...)來配置屬性描述符。
當設置了writable為false時扒俯,該屬性的值無法修改奶卓。

Object.defineProperty(obj, 'a', {writable: false});
obj.a = 'b'; //obj.a = 'a'

當設置了configurable為false時,無法重新配置該屬性的特性撼玄,且無法刪除該屬性夺姑,該操作是不可逆的。(唯一可以設置的情況是掌猛,將writable為true 改為writable為false)

Object.defineProperty(obj, 'a', {configurable: false});
delete obj.a //obj.a = 'a';
Object.defineProperty(obj, 'a', {configurable: true}); //Type Error
Object.defineProperty(obj, 'a', {writable: false});
obj.a = 'aa'; //obj = {a: 'a'}

禁止擴展

Object.preventExtensions(...)防止后續(xù)向?qū)ο笮略鰧傩浴?/p>

let obj = {a: 'a'};
Object.preventExtensions(obj);
obj.b = 'b'; //obj = {a: 'a'}
console.log(Object.isExtensible(obj)); //false

密封對象

Object.seal(...)可以創(chuàng)建一個密封的對象盏浙,該對象的屬性不可擴展、配置荔茬、刪除废膘,但可以修改。實際上該方法就是對對象先用Object.preventExtensions禁止擴展屬性慕蔚,再將對象所有屬性的configurable特性設置false丐黄。

let obj = {a: 'a', b: 'b'};
Object.seal(obj);
obj.c = 'c'; //obj = {a: 'a', b: 'b'}
delete obj.a;
delete obj.b; //obj = {a: 'a', b: 'b'}
obj.a = 'aa'; //obj = {a: 'aa', b: 'b'}
console.log(Object.isSealed(obj)); //true

凍結(jié)對象

Object.freeze(...)可以創(chuàng)建一個凍結(jié)的對象,該對象的屬性不可擴展坊萝、配置孵稽、刪除、修改十偶,是js中對象最高不可變性菩鲜。實際上該方法就是調(diào)用Object.seal(...)將對象設置成密封對象后,在將所有數(shù)據(jù)訪問屬性設置為writable:false惦积。

let obj = {a: 'a', b: 'b'};
Object.freeze(obj);
obj.c = 'c'; //obj = {a: 'a', b: 'b'}
delete obj.a;
delete obj.b; //obj = {a: 'a', b: 'b'}
obj.a = 'aa'; //obj = {a: 'a', b: 'b'}
console.log(Object.isFrozen(obj)); //true

這個方法是你可以應用在對象上的級別最高的不可變性接校,它會禁止對于對象本身及其任意直接屬性的修改(不過這個對象引用的其他對象是不受影響的)。

注意

這里對象中的不可變性都是淺不變性,如果屬性引用的是對象蛛勉、數(shù)組等引用類型鹿寻,該引用的對象、數(shù)組本身都是可變的(比如往數(shù)組里添加元素)诽凌,除非再把每個引用類型屬性遞歸凍結(jié)毡熏。

let obj = {a: [1, 2]};
Object.freeze(obj);
obj.a.push(3); //obj = {a: [1, 2, 3]}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市侣诵,隨后出現(xiàn)的幾起案子痢法,更是在濱河造成了極大的恐慌,老刑警劉巖杜顺,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件财搁,死亡現(xiàn)場離奇詭異,居然都是意外死亡躬络,警方通過查閱死者的電腦和手機尖奔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來穷当,“玉大人提茁,你說我怎么就攤上這事”毂酰” “怎么了甘凭?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長火邓。 經(jīng)常有香客問我丹弱,道長,這世上最難降的妖魔是什么铲咨? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任躲胳,我火速辦了婚禮,結(jié)果婚禮上纤勒,老公的妹妹穿的比我還像新娘坯苹。我一直安慰自己,他們只是感情好摇天,可當我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布粹湃。 她就那樣靜靜地躺著,像睡著了一般泉坐。 火紅的嫁衣襯著肌膚如雪为鳄。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天腕让,我揣著相機與錄音孤钦,去河邊找鬼。 笑死,一個胖子當著我的面吹牛偏形,可吹牛的內(nèi)容都是我干的静袖。 我是一名探鬼主播,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼俊扭,長吁一口氣:“原來是場噩夢啊……” “哼队橙!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起萨惑,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤喘帚,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后咒钟,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡若未,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年朱嘴,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片粗合。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡萍嬉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出隙疚,到底是詐尸還是另有隱情壤追,我是刑警寧澤,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布供屉,位于F島的核電站行冰,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏伶丐。R本人自食惡果不足惜悼做,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望哗魂。 院中可真熱鬧肛走,春花似錦、人聲如沸录别。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽组题。三九已至葫男,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間往踢,已是汗流浹背腾誉。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人利职。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓趣效,卻偏偏與公主長得像,于是被迫代替她去往敵國和親猪贪。 傳聞我的和親對象是個殘疾皇子跷敬,可洞房花燭夜當晚...
    茶點故事閱讀 45,675評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 概述 JavaScript提供了一個內(nèi)部數(shù)據(jù)結(jié)構(gòu),用來描述一個對象的屬性的行為热押,控制它的行為西傀。這被稱為“屬性描述對...
    許先生__閱讀 493評論 0 1
  • 函數(shù)和對象 1、函數(shù) 1.1 函數(shù)概述 函數(shù)對于任何一門語言來說都是核心的概念桶癣。通過函數(shù)可以封裝任意多條語句拥褂,而且...
    道無虛閱讀 4,581評論 0 5
  • 概述 JavaScript提供了一個內(nèi)部數(shù)據(jù)結(jié)構(gòu),用來描述一個對象的屬性的行為牙寞,控制它的行為饺鹃。這被稱為“屬性描述對...
    zjh111閱讀 728評論 0 0
  • 官方中文版原文鏈接 感謝社區(qū)中各位的大力支持,譯者再次奉上一點點福利:阿里云產(chǎn)品券间雀,享受所有官網(wǎng)優(yōu)惠悔详,并抽取幸運大...
    HetfieldJoe閱讀 2,597評論 9 22
  • 我們必須要 不斷提醒自己要強大 因為 脆弱無處不在 《潮騷~蔡振源》
    蔡振源閱讀 257評論 0 1