如何讓對(duì)象屬性不可配置或枚舉

一、什么是屬性描述符?

MDN:

對(duì)象里目前存在的屬性描述符有兩種主要形式:數(shù)據(jù)描述符和存取描述符阳仔。

數(shù)據(jù)描述符是一個(gè)擁有可寫或不可寫值的屬性攒霹。

存取描述符是由一對(duì) getter-setter 函數(shù)功能來(lái)描述的屬性怯疤。

描述符必須是兩種形式之一;不能同時(shí)是兩者催束。

數(shù)據(jù)描述符和存取描述符均具有以下可選鍵值:

value 與屬性相關(guān)的值集峦。可以是任何有效的 JavaScript 值(數(shù)值抠刺,對(duì)象塔淤,函數(shù)等)。默認(rèn)為 undefined速妖。?

writable true 當(dāng)且僅當(dāng)可能用賦值運(yùn)算符改變與屬性相關(guān)的值高蜂。默認(rèn)為 false。

存取描述符同時(shí)具有以下可選鍵值:

get

一個(gè)給屬性提供 getter 的方法罕容,如果沒有 getter 則為 undefined备恤。方法將返回用作屬性的值稿饰。默認(rèn)為 undefined。 set 一個(gè)給屬性提供 setter 的方法露泊,如果沒有 setter 則為 undefined喉镰。該方法將收到作為唯一參數(shù)的新值分配給屬性。默認(rèn)為 undefined惭笑。

以上是摘自MDN的解釋梧喷,看起來(lái)是很晦澀的,具體什么意思呢: 首先我們從以上解釋知道該匿名參數(shù)對(duì)象有個(gè)很好聽的名字叫屬性描述符脖咐,屬性描述符又分成兩大塊:數(shù)據(jù)描述符以及存取描述符(其實(shí)只是一個(gè)外號(hào)铺敌,給指定的屬性集合起個(gè)外號(hào))。

數(shù)據(jù)描述符包括兩個(gè)屬性 :value屬性以及writable屬性屁擅,第一個(gè)屬性用來(lái)聲明當(dāng)前欲修飾的屬性的值偿凭,第二個(gè)屬性用來(lái)聲明當(dāng)前對(duì)象是否可寫即是否可以修改

存取描述符就包括get與set屬性用來(lái)聲明欲修飾的象屬性的getter及setter

屬性描述符內(nèi)部,數(shù)據(jù)描述符與存取描述符只能存在其中之一派歌,但是不論使用哪個(gè)描述符都可以同時(shí)設(shè)置configurable屬性以及enumerable屬性弯囊。

configurable屬性用來(lái)聲明欲修飾的屬性是否能夠配置,僅有當(dāng)其值為true時(shí)胶果,被修飾的屬性才有可能能夠被刪除匾嘱,或者重新配置。

enumerable屬性用來(lái)聲明欲修飾屬性是否可以被枚舉早抠。

知道了什么是屬性描述符霎烙,我們就可以開始著手創(chuàng)建一些對(duì)象并開始配置其屬性

順便給大家推薦一個(gè)裙,它的前面是 537蕊连,中間是631悬垃,最后就是 707。想要學(xué)習(xí)前端的小伙伴可以加入我們一起學(xué)習(xí)甘苍,互相幫助尝蠕。群里每天晚上都有大神免費(fèi)直播上課,如果不是想學(xué)習(xí)的小伙伴就不要加啦载庭。(537-631-707)

二看彼、創(chuàng)建屬性不可配置不可枚舉的對(duì)象

//使用默認(rèn)值配置

(function(){

varobj?=?{};//聲明一個(gè)空對(duì)象

Object.defineProperty(obj,"key",{

value:"static"

//沒有設(shè)置?enumerable?使用默認(rèn)值?false

//沒有?configurable?使用默認(rèn)值?false

//沒有?writable?使用默認(rèn)值?false

});

console.log(obj.key);//輸出?“static”

obj.key?="new"http://嘗試修改其值,修改將失敗,因?yàn)?writable?為?false

console.log(obj.key);//輸出?“static”

obj.a?=1;//動(dòng)態(tài)添加一個(gè)屬性

for(variteminobj){//遍歷所有?obj?的可枚舉屬性

console.log(item);

}//只輸出一個(gè)?“a”?因?yàn)?“key”的?enumerable為?false

})();

//顯示配置?等價(jià)于上面

(function(){

varobj?=?{};

Object.defineProperty(obj,"key",{

enumerable:false,

configurable:false,

writable:false,

value:"static"

})

})();

//等價(jià)配置

(function(){

varo?=?{};

o.a?=1;

//等價(jià)于

Object.defineProperty(o,"a",{value:1,

writable:true,

configurable:true,

enumerable:true});

Object.defineProperty(o,"a",{value:1});

//等價(jià)于

Object.defineProperty(o,"a",{value:1,

writable:false,

configurable:false,

enumerable:false});

})();

三、Enumerable 特性

屬性特性enumerable決定屬性是否能被for...in循環(huán)或Object.keys方法遍歷得到

(function(){

varo?=?{};

Object.defineProperty(o,"a",{value:1,enumerable:true});

Object.defineProperty(o,"b",{value:2,enumerable:false});

Object.defineProperty(o,"c",{value:2});//enumerable?default?to?false

o.d?=4;//如果直接賦值的方式創(chuàng)建對(duì)象的屬性,則這個(gè)屬性的?enumerable?為?true

for(varitemino){//遍歷所有可枚舉屬性包括繼承的屬性

console.log(item);

}

console.log(Object.keys(o));//獲取?o?對(duì)象的所有可遍歷屬性不包括繼承的屬性

console.log(o.propertyIsEnumerable('a'));//true

console.log(o.propertyIsEnumerable('b'));//false

console.log(o.propertyIsEnumerable('c'));//false

})();

輸出結(jié)果如下:

四囚聚、Configurable 特性

(function(){

varo?=?{};

Object.defineProperty(o,"a",{get:function(){return1;},

configurable:false}?);

//enumerable?默認(rèn)為?false,

//value?默認(rèn)為?undefined,

//writable?默認(rèn)為?false,

//set?默認(rèn)為?undefined

//拋出異常,因?yàn)樽铋_始定義了?configurable?為?false,故后期無(wú)法對(duì)其進(jìn)行再配置

Object.defineProperty(o,"a",{configurable:true}?);

//拋出異常,因?yàn)樽铋_始定義了?configurable?為?false,故后期無(wú)法對(duì)其進(jìn)行再配置,enumerable?的原值為?false

Object.defineProperty(o,"a",{enumerable:true}?);

//拋出異常,因?yàn)樽铋_始定義了?configurable?為?false,set的原值為?undefined

Object.defineProperty(o,"a",{set:function(val){}}?);

//拋出異常,因?yàn)樽铋_始定義了?configurable?為?false,故無(wú)法進(jìn)行覆蓋,盡管想用一樣的來(lái)覆蓋

Object.defineProperty(o,"a",{get:function(){return1}});

//拋出異常靖榕,因?yàn)樽铋_始定義了?configurable?為?false,故無(wú)法將其進(jìn)行重新配置把屬性描述符從存取描述符改為數(shù)據(jù)描述符

Object.defineProperty(o,"a",{value:12});

console.log(o.a);//輸出1

deleteo.a;//想要?jiǎng)h除屬性,將失敗

console.log(o.a);//輸出1

})();

五、提高及擴(kuò)展

1.屬性描述符中容易被誤導(dǎo)的地方之writable與configurable

(function(){

varo?=?{};

Object.defineProperties(o,{

"a":?{

value:1,

writable:true,//可寫

configurable:false//不可配置

//enumerable?默認(rèn)為?false?不可枚舉

},

"b":{

get:function(){

returnthis.a;

},

configurable:false

}

});

console.log(o.a);//1

o.a?=2;//修改值成功,writable?為?true

console.log(o.a);//2

Object.defineProperty(o,"a",{value:3});//同樣為修改值成功

console.log(o.a);//3

//將其屬性?b?的屬性描述符從存取描述符重新配置為數(shù)據(jù)描述符

Object.defineProperty(o,"b",{value:3});//拋出異常,因?yàn)?configurable?為?false

})();

2.通過上面的學(xué)習(xí)靡挥,我們都知道傳遞屬性描述符參數(shù)時(shí)序矩,是定義一個(gè)匿名的對(duì)象,里面包含屬性描述符內(nèi)容跋破,若每定義一次便要?jiǎng)?chuàng)建一個(gè)匿名對(duì)象傳入簸淀,將會(huì)造成內(nèi)存浪費(fèi)瓶蝴。故優(yōu)化如下:

(function(){

varobj?=?{};

//回收同一對(duì)象,即減少內(nèi)存浪費(fèi)

functionwithValue(value){

vard?=?withValue.d?||(

withValue.d?=?{

enumerable:false,

configurable:false,

writable:false,

value:null

}

);

d.value?=?value;

returnd;

}

Object.defineProperty(obj,"key",withValue("static"))

})();

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市租幕,隨后出現(xiàn)的幾起案子舷手,更是在濱河造成了極大的恐慌,老刑警劉巖劲绪,帶你破解...
    沈念sama閱讀 212,029評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件男窟,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡贾富,警方通過查閱死者的電腦和手機(jī)歉眷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,395評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)颤枪,“玉大人汗捡,你說(shuō)我怎么就攤上這事∥犯伲” “怎么了扇住?”我有些...
    開封第一講書人閱讀 157,570評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)盗胀。 經(jīng)常有香客問我艘蹋,道長(zhǎng),這世上最難降的妖魔是什么票灰? 我笑而不...
    開封第一講書人閱讀 56,535評(píng)論 1 284
  • 正文 為了忘掉前任女阀,我火速辦了婚禮,結(jié)果婚禮上米间,老公的妹妹穿的比我還像新娘强品。我一直安慰自己,他們只是感情好屈糊,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,650評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著琼了,像睡著了一般逻锐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上雕薪,一...
    開封第一講書人閱讀 49,850評(píng)論 1 290
  • 那天昧诱,我揣著相機(jī)與錄音,去河邊找鬼所袁。 笑死盏档,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的燥爷。 我是一名探鬼主播蜈亩,決...
    沈念sama閱讀 39,006評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼懦窘,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了稚配?” 一聲冷哼從身側(cè)響起畅涂,我...
    開封第一講書人閱讀 37,747評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎道川,沒想到半個(gè)月后午衰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,207評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡冒萄,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,536評(píng)論 2 327
  • 正文 我和宋清朗相戀三年臊岸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片尊流。...
    茶點(diǎn)故事閱讀 38,683評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡帅戒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出奠旺,到底是詐尸還是另有隱情蜘澜,我是刑警寧澤,帶...
    沈念sama閱讀 34,342評(píng)論 4 330
  • 正文 年R本政府宣布响疚,位于F島的核電站鄙信,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏忿晕。R本人自食惡果不足惜装诡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,964評(píng)論 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望践盼。 院中可真熱鬧鸦采,春花似錦、人聲如沸咕幻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,772評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)肄程。三九已至锣吼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蓝厌,已是汗流浹背玄叠。 一陣腳步聲響...
    開封第一講書人閱讀 32,004評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拓提,地道東北人读恃。 一個(gè)月前我還...
    沈念sama閱讀 46,401評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親寺惫。 傳聞我的和親對(duì)象是個(gè)殘疾皇子疹吃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,566評(píng)論 2 349

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

  • 一、什么是屬性描述符肌蜻? MDN: 對(duì)象里目前存在的屬性描述符有兩種主要形式:數(shù)據(jù)描述符和存取描述符互墓。 數(shù)據(jù)描述符是...
    強(qiáng)哥科技興閱讀 887評(píng)論 0 0
  • 概述 JavaScript提供了一個(gè)內(nèi)部數(shù)據(jù)結(jié)構(gòu),用來(lái)描述一個(gè)對(duì)象的屬性的行為蒋搜,控制它的行為篡撵。這被稱為“屬性描述對(duì)...
    zjh111閱讀 724評(píng)論 0 0
  • 概述 JavaScript提供了一個(gè)內(nèi)部數(shù)據(jù)結(jié)構(gòu),用來(lái)描述一個(gè)對(duì)象的屬性的行為豆挽,控制它的行為育谬。這被稱為“屬性描述對(duì)...
    許先生__閱讀 484評(píng)論 0 1
  • 盡管javascript里有大量?jī)?nèi)建引用對(duì)象,很可能你還說(shuō)會(huì)頻繁創(chuàng)建自己的對(duì)象帮哈。當(dāng)你在這么做的時(shí)候膛檀,記得javas...
    WanLum閱讀 527評(píng)論 1 3
  • (注1:如果有問題歡迎留言探討,一起學(xué)習(xí)娘侍!轉(zhuǎn)載請(qǐng)注明出處咖刃,喜歡可以點(diǎn)個(gè)贊哦!)(注2:更多內(nèi)容請(qǐng)查看我的目錄憾筏。) ...
    love丁酥酥閱讀 1,854評(píng)論 4 7