Object的一些靜態(tài)方法(2)

開場白

很抱歉,開始講述知識點之前還是要讓你看一段不那么重要的開場白忆首。

今天去了自己最為向往的公司參加了第二輪面試柱搜,跟CEO聊天的感覺真的非常好夫凸,希望自己能進去吧。但是不管怎么說,日子總得要過吧蒜绽。如果真的不幸沒有辦法進入該公司,或許我能做的也就是整理著裝,重新踏上求職之旅吧。不過在這之前楣导,還是要每天學點javascript吧?

今天主要講述下面這兩組方法

1. Object.keysObject.getOwnPropertyNames的異同片仿。

2. Object.seal, Object.preventExtensions以及Object.freeze可以在不同程度增強對象的健壯性。

正文

1. Object.keysObject.getOwnPropertyNames的異同

兩個方法都是可以用來獲取指定對象的自有屬性的尤辱。那么它們有什么不同呢砂豌?
之前已經稍微提及過Object.keys了,它是用來獲取一個對象的自有屬性光督。比如:

> var a = {x: 1, y: 2}
undefined
> a
{ x: 1, y: 2 }
> Object.keys(a)
[ 'x', 'y' ]

那它有什么局限呢阳距?更確切地說它只能用來獲取對象可枚舉的自有屬性,我們看看下面的例子结借。

> Object.getOwnPropertyDescriptor(a, 'x')
{ value: 1, writable: true, enumerable: true, configurable: true }

> Object.defineProperty(a, 'x', {enumerable: false}) // 設置x屬性為不可枚舉的
{ y: 2 }

> a
{ y: 2 }

> Object.keys(a)
[ 'y' ]

可見筐摘,現在我們只能獲取到對象a的自有的并且是可枚舉的屬性。如何獲得對象a的自有屬性船老,并且不管它們是否是可枚舉的呢咖熟?這個時候我們可以考慮用Object.getOwnPropertyNames

> Object.getOwnPropertyNames(a)
[ 'x', 'y' ]

這樣就可以獲取對象a的所有自有的屬性努隙,包括了不可枚舉的屬性球恤。如果我們需要遍歷對象a的所有自有屬性辜昵,這個方法就能派上用場了荸镊。

2. Object.seal, Object.preventExtensions以及Object.freeze可以在不同程度增強對象的健壯性。

這里就有一個問題,什么是對象的可擴展性?我用比較直白的話說就是“是否能夠為這個對象添加屬性?”躬存。我們可以用Object.isExtensible來判斷對象是否是可以擴展的。

> Object.isExtensible(1)
false
> Object.isExtensible({})
true
> Object.isExtensible("lanzhiheng")
false

字符串不可以擴展?你在逗我嗎幽崩?對的呼盆,我們這里用的是字符串的字面量,它是不可以擴展的盾剩。做個實驗:

> var str = "lanzhiheng"
undefined
> str.age = 12
12
> str.age
undefined

我們試圖給str添加一個屬性雷激,然而最后查找的時候并沒有設置成功,原因是

當我們添加屬性的時候告私,JS會臨時創(chuàng)建一個字符串的對象屎暇,并且它包裝了原來的字符串字面量,所以這里并不會報錯驻粟。但是當我們執(zhí)行完str.age = 12之后這個對象自動銷毀了根悼,所以這個屬性添加是沒有作用的。

好啦蜀撑,回到正題挤巡,下面是ES5之后才有的靜態(tài)方法。我們按順序來說說酷麦。

1. Object.preventExtensions 讓對象變成不可擴展的

來看例子:

> var b = {x: 1, y: 2}
undefined
> b.z = 13
13

> Object.preventExtensions(b) // 保護可擴展性
{ x: 1, y: 2, z: 13 }

> b.k = 100
100
> b
{ x: 1, y: 2, z: 13 }

可見矿卑,一開始給對象b添加屬性是可以的,然而贴铜,我們調用了Object.preventExtensions之后這個設置就失敗了粪摘,在嚴格模式下甚至還會報錯

TypeError: Can't add property x, object is not extensible

2. Object.seal 讓對象變成不可擴展的并且把已有的屬性設置成不可配置的

這里我們簡單把不可配置理解成不可刪除,(當然絕不是那么簡單而已)。我們來操作一下新對象c绍坝。

> c = {x: 1, y: 2, z: 3}
{ x: 1, y: 2, z: 3 }

> c.kk = 12  // 添加屬性
12

> c
{ x: 1, y: 2, z: 3, kk: 12 }

> delete c.kk // 刪除屬性
true

> c
{ x: 1, y: 2, z: 3 }

目前為止是很正常的徘意,現在用Object.seal來處理一下好吧。

> Object.seal(c)
{ x: 1, y: 2, z: 3 }

> c.kk = 1000 // 添加屬性
1000

> c  // 無效
{ x: 1, y: 2, z: 3 }
> delete c.x // 刪除屬性
false

> c // 無效
{ x: 1, y: 2, z: 3 }

發(fā)現處理之后對c對象進行擴展以及刪除屬性這些操作都不生效了(嚴格模式下還會報錯)轩褐,這就是Object.seal方法的作用椎咧。可以保護對象的屬性以及對象本身, 我們可以方便地用Object.isSealed來判斷對象是否具有這類屬性把介。

> Object.isSealed(c)
true

同時勤讽,我們也可以用來判斷對象是否具有不可擴展且屬性不可配置這些特征,即便它沒有經過Object.seal處理

> var a = {x: 1, y: 2}
undefined

// 設置對象為不可擴展的
> Object.preventExtensions(a)
{ x: 1, y: 2 }
> Object.isSealed(a)
false

// 設置對應的屬性的特性為不可配置的
> Object.defineProperties(a, {x: {configurable: false}, y: {configurable: false}})
{ x: 1, y: 2 }

> Object.isSealed(a)
true

這個方法是不是還不錯?另外, 雖然我們無法對對象的已有結構進行修改拗踢,但是我們卻依然可以修改對象已有的屬性的值

> c
{ x: 1, y: 2, z: 3 }
> c.x = 100
100
> c
{ x: 100, y: 2, z: 3 }

要怎樣更進一步方便地提高健壯性脚牍,把所有屬性都弄成不可寫的,并且不可配置的呢巢墅?這個時候會用到下面要介紹的Object.freeze方法诸狭。

3. Object.freeze 讓對象變成不可擴展的, 并且把已有的屬性設置成不可配置并且不可寫

這里不多說明券膀,直接舉例子

> var d = {x: 1, y: 2, c: 3}
undefined

> Object.freeze(d)
{ x: 1, y: 2, c: 3 }

> d.kk = 100 // 擴展對象d
100
> d
{ x: 1, y: 2, c: 3 }

> delete d.x // 刪除對象d屬性
false
> d
{ x: 1, y: 2, c: 3 }

> d.x = 100 // 修改對象d屬性的值
100

> d
{ x: 1, y: 2, c: 3 }

可見對象d進行了上面操作依然沒有任何改變。同樣的, 我們也可以用Object.isFrozen來判斷對象是否有對應的特性驯遇。

> Object.isFrozen(d)
true

這里就不用復雜的例子了芹彬,跟Object.isSealed是差不多的。

當然叉庐,如果要對這些進行過保護的特性進行非法操作舒帮,在嚴格模式下是會拋出異常的。

> var dStrict = {x: 1, y: 2}
undefined

> Object.freeze(dStrict)
{ x: 1, y: 2 }

> dStrict.x = 100
TypeError: Cannot assign to read only property 'x' of object '#<Object>'

以上這點寫代碼的時候需要注意一下陡叠。畢竟嚴格模式跟非嚴格模式有很多行為都是有所區(qū)別的玩郊。

最后

終于到了尾聲了,今天介紹的方法稍微多了一些枉阵,不過都是相關聯(lián)并且比較方便記憶的瓦宜,希望讀者閱讀的時候不會太難受。

Happy Writing & Coding

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末岭妖,一起剝皮案震驚了整個濱河市临庇,隨后出現的幾起案子,更是在濱河造成了極大的恐慌昵慌,老刑警劉巖假夺,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異斋攀,居然都是意外死亡已卷,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門淳蔼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來侧蘸,“玉大人,你說我怎么就攤上這事鹉梨』浒” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵存皂,是天一觀的道長晌坤。 經常有香客問我,道長旦袋,這世上最難降的妖魔是什么骤菠? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮疤孕,結果婚禮上商乎,老公的妹妹穿的比我還像新娘。我一直安慰自己祭阀,他們只是感情好鹉戚,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布爬泥。 她就那樣靜靜地躺著,像睡著了一般崩瓤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上踩官,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天却桶,我揣著相機與錄音,去河邊找鬼蔗牡。 笑死颖系,一個胖子當著我的面吹牛,可吹牛的內容都是我干的辩越。 我是一名探鬼主播嘁扼,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼黔攒!你這毒婦竟也來了趁啸?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤督惰,失蹤者是張志新(化名)和其女友劉穎不傅,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體赏胚,經...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡访娶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了觉阅。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片崖疤。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖典勇,靈堂內的尸體忽然破棺而出劫哼,到底是詐尸還是另有隱情,我是刑警寧澤割笙,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布沦偎,位于F島的核電站,受9級特大地震影響咳蔚,放射性物質發(fā)生泄漏豪嚎。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一谈火、第九天 我趴在偏房一處隱蔽的房頂上張望侈询。 院中可真熱鬧,春花似錦糯耍、人聲如沸扔字。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽革为。三九已至扭粱,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間震檩,已是汗流浹背琢蛤。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留抛虏,地道東北人博其。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像迂猴,于是被迫代替她去往敵國和親慕淡。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內容