自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

JS屬性特性(屬性描述符)

開發(fā) 前端
ECMAScript 5 中定義了一個名叫“屬性描述符”的對象,用于描述了的各種特征?!皩傩悦枋龇睂ο笾荒茉贠bject.defineProperty或Object.defineProperties中使用。

[[174790]]

概念

ECMAScript 5 中定義了一個名叫“屬性描述符”的對象,用于描述了的各種特征。屬性描述符對象有4個屬性:

  • configurable:可配置性,控制著其描述的屬性的修改,表示能否修改屬性的特性,能否把屬性修改為訪問器屬性,或者能否通過delete刪除屬性從而重新定義屬性。默認(rèn)值為true。
  • enumerable:可枚舉性,表示能否通過for-in遍歷得到屬性。默認(rèn)值為true。
  • writable:可寫性,表示能否修改屬性的值。默認(rèn)值為true。
  • value:數(shù)據(jù)屬性,表示屬性的值。默認(rèn)值為undefined。

除了上面的屬性,還有兩個存取器屬性,分別是get和set,可以代替value和writable。

  • get:在讀取屬性時調(diào)用的函數(shù)。只指定get則表示屬性為只讀屬性。默認(rèn)值為undefined。
  • set:在寫入屬性時調(diào)用的函數(shù)。只指定set則表示屬性為只寫屬性。默認(rèn)值為undefined。

使用

“屬性描述符”對象只能在Object.defineProperty或Object.defineProperties中使用。

API 用法

Object.defineProperty:https://developer.mozilla.org...

Object.defineProperties: https://developer.mozilla.org...

  1. var hello = {} 
  2.  
  3. Object.defineProperty(hello, 'girl', { 
  4.     configurable: false
  5.     enumberable: false
  6.     writable: true
  7.     value: 'sexy' 
  8. }) 
  9.  
  10. // 存取器 
  11. Object.defineProperty(hello, 'woman', { 
  12.     configurable: false
  13.     enumberable: false
  14.     get: function() { 
  15.         return this.girl 
  16.     }, 
  17.     setfunction(val) { 
  18.         this.girl = val 
  19.     } 
  20. }) 
  21.  
  22. // 定義多個屬性 
  23. Object.defineProperties(hello, { 
  24.     boy: { 
  25.         configurable: false
  26.         enumberable: false
  27.         writable: false
  28.         value: 'handsome' 
  29.     }, 
  30.     man: { 
  31.         configurable: false
  32.         enumberable: false
  33.         writable: true
  34.         get: function() { 
  35.             return this.boy 
  36.         } 
  37.     } 
  38. })  

當(dāng)用Object.defineProperty或Object.defineProperties操作(新建或者修改)那些不允許創(chuàng)建或修改的屬性時,會拋出類型錯誤異常。

  1. // 此例子運行在前面的例子的基礎(chǔ)上 
  2. Object.defineProperty(hello, 'boy', { 
  3.     writable: true 
  4. })    // Uncaught TypeError: Cannot redefine property: boy  

因為前面boy屬性已經(jīng)被設(shè)置為不可配置,所以這里修改writable會拋出類型錯誤異常。

通過Object.getOwnPropertyDescriptor或者Object.getOwnPropertyDescriptors可以得到屬性描述符。

API 用法

Object.getOwnPropertyDscriptor:https://developer.mozilla.org...

Object.getOwnPropertyDescriptors:https://developer.mozilla.org...

規(guī)則

  1. var rules = { 
  2.     common: 'test' 
  3.  

如果屬性是不可配置的,則不能修改它的可配置性和可枚舉性。

  1. Object.defineProperty(rules, 'rule1', { 
  2.     configurable: false
  3.     enumberable: false 
  4. }) 
  5.  
  6. // 修改configurable會拋出類型錯誤異常 
  7. Object.defineProperty(rules, 'rule1', { 
  8.     configurable: true 
  9. })    // Uncaught TypeError: Cannot redefine property: rule1 
  10.  
  11. // 修改enumberable不會拋出異常,但enmuberable沒有被修改 
  12. Object.defineProperty(rules, 'rule1', { 
  13.     enumberable: true 
  14. }) 
  15. Object.getOwnPropertyDescriptor(rules, 'rule1')    // Object {value: undefined, writable: false, enumerable: false, configurable: false 

如果存取器屬性是不可配置的,則不能修改get和set方法,也不能將它轉(zhuǎn)換為數(shù)據(jù)屬性。

  1. Object.defineProperty(rules, 'rule2', { 
  2.     configurable: false
  3.     enumberable: false
  4.     get: function() { 
  5.         return this.common 
  6.     }, 
  7.     setfunction(val) { 
  8.         this.common = val 
  9.     } 
  10. }) 
  11.  
  12. // 修改get或者set方法會拋出類型錯誤異常 
  13. Object.defineProperty(rules, 'rule2', { 
  14.     get: function() { 
  15.         return this.common + 'rule2' 
  16.     } 
  17. })    // Uncaught TypeError: Cannot redefine property: rule2 
  18.  
  19. Object.defineProperty(rules, 'rule2', { 
  20.     setfunction(val) { 
  21.         this.common = 'rule2' 
  22.     } 
  23. })    // Uncaught TypeError: Cannot redefine property: rule2 
  24.  
  25. // 將它轉(zhuǎn)換為數(shù)據(jù)屬性同樣會拋出類型錯誤異常 
  26. Object.defineProperty(rules, 'rule2', { 
  27.     value: 'rule2' 
  28. })    // Uncaught TypeError: Cannot redefine property: rule2  

如果數(shù)據(jù)屬性是不可配置的,則不能將它轉(zhuǎn)換為存取器屬性;同時,也不能將它的可寫性從false修改為true,但可以從true修改為false。

  1. Object.defineProperty(rules, 'rule3', { 
  2.     configurable: false
  3.     writable: false
  4.     value: 'rule3' 
  5. }) 
  6.  
  7. // 修改writable為true會拋出類型錯誤異常 
  8. Object.defineProperty(rules, 'rule3', { 
  9.     writable: true 
  10. }) 
  11.  
  12.  
  13. Object.defineProperty(rules, 'rule4', { 
  14.     configurable: false
  15.     writable: true
  16.     value: 'rule4' 
  17. }) 
  18.  
  19. // 可以修改writable為false 
  20. Object.defineProperty(rules, 'rule4', { 
  21.     writable: false 
  22. }) 
  23. Object.getOwnPropertyDescriptor(rules, 'rule4')    //   Object {value: "rule4", writable: false, enumerable: false, configurable: false 

如果數(shù)據(jù)屬性是不可配置且不可寫的,則不能修改他的值;如果是可配置但不可寫,則可以修改他的值(實際上是先將它標(biāo)記為可寫的,然后修改它的值,***再將它標(biāo)記回不可寫)。

其實這里所說的修改值,是通過Object.defineProperty或Object.defineProperties方法修改。通過直接賦值的方法在數(shù)據(jù)屬性不可配置的情況下是不能修改屬性值的。

  1. Object.defineProperty(rules, 'rule5', { 
  2.     configurable: false
  3.     writable: false
  4.     value: 'rule5' 
  5. }) 
  6.  
  7. // 修改屬性值會拋出類型錯誤異常 
  8. Object.defineProperty(rules, 'rule5', { 
  9.     value: 'rule55' 
  10. })    // Uncaught TypeError: Cannot redefine property: rule5 
  11.  
  12. rules.rule5 = 'rule55' 
  13. // 值沒有被修改,也不會拋出異常 
  14. rules.rule5            // 'rule5' 
  15.  
  16.  
  17. Object.defineProperty(rules, 'rule6', { 
  18.     configurable: true
  19.     writable: false
  20.     value: 'rule6' 
  21. }) 
  22.  
  23. // 修改屬性值 
  24. Object.defineProperty(rules, 'rule6', { 
  25.     value: 'rule66' 
  26. }) 
  27. rules.rule6            // 'rule66' 
  28.  
  29. rules.rule6 = 'rule6' 
  30. // 值沒有被修改,也不會修改 
  31. rules.rule6            // 'rule6'  

只指定set不能讀,如果嘗試讀取該屬性值,返回undefined。(紅寶書上說在嚴(yán)格模式下才拋出異常,但沒有)

  1. Object.defineProperty(rules, 'rule7', { 
  2.     get: function() { 
  3.         return this.common 
  4.     } 
  5. }) 
  6. rules.rule7 = 'rule7'    // Uncaught TypeError: Cannot redefine property: rule7  

如果對象是不可擴(kuò)展的,則可以編輯已有的自有屬性,但不能給它添加新屬性。

操作對象可擴(kuò)展性的API有三個:Object.preventExtensions、Object.seal、Object.freeze。

API 用法

Object.preventExtensions:https://developer.mozilla.org...

Object.seal:https://developer.mozilla.org...

Object.freeze:https://developer.mozilla.org...

Object.isExtensions:https://developer.mozilla.org...

Object.isSealed:https://developer.mozilla.org...

Object.isFrozen:https://developer.mozilla.org...

使用Object.preventExtensions可以將對象轉(zhuǎn)換為不可擴(kuò)展。

使用Object.isExtensions來判斷對象是否可擴(kuò)展。

  1. var ex = {} 
  2. Object.defineProperty(ex, 'ex1', { 
  3.     configurable: true
  4.     writable: true
  5.     value: 'ex1' 
  6. }) 
  7. Object.isExtensible(ex)        // true 
  8. Object.preventExtensions(ex) 
  9. Object.isExtensible(ex)        // false 
  10.  
  11. // 可以修改已有的屬性 
  12. Object.defineProperty(ex, 'ex1', { 
  13.     writable: false
  14.     value: 'ex11' 
  15. }) 
  16. Object.getOwnPropertyDescriptor(ex, 'ex1')    // Object {value: "ex11", writable: false, enumerable: false, configurable: true
  17.  
  18. // 添加屬性會拋出類型錯誤異常 
  19. Object.defineProperty(ex, 'ex2', { 
  20.     value: 'ex2' 
  21. })    // Uncaught TypeError: Cannot define property:ex2, object is not extensible.  

使用Object.seal除了可以將對象轉(zhuǎn)換為不可擴(kuò)展的,還可以將對象的所有自有屬性都轉(zhuǎn)換為不可配置的。即不能給對象添加新屬性,而且它已有的屬性也不能刪除或者配置(這里同樣會遵循前面的規(guī)則)。

使用Object.isSealed來判斷對象是否封閉(sealed)。

  1. var se = {} 
  2. Object.defineProperty(se, 'se1', { 
  3.     configurable: true
  4.     writable: false
  5.     value: 'se1' 
  6. }) 
  7. Object.isSealed(se)        // false 
  8. Object.seal(se) 
  9. Object.isSealed(se)        // true 
  10.  
  11. // 修改已有的屬性會拋出類型錯誤異常 
  12. Object.defineProperty(se, 'se1', { 
  13.     writable: true
  14.     value: 'se11' 
  15. })    // Uncaught TypeError: Cannot redefine property: se1 
  16.  
  17. // 添加屬性會拋出類型錯誤異常 
  18. Object.defineProperty(se, 'se2', { 
  19.     value: 'se2' 
  20. })    // Uncaught TypeError: Cannot define property:se2, object is not extensible.  

使用Object.freeze除了將對象轉(zhuǎn)換為不可擴(kuò)展的和將其屬性轉(zhuǎn)換為不可配置的之外,還可以將自有屬性轉(zhuǎn)換為只讀。(如果對象設(shè)置了set,存取器屬性將不會受影響,仍可以調(diào)用set方法,而且不會拋出異常,但如果set方法是改變該對象的屬性,則不能修改成功)

使用Object.isFrozen來檢測對象是否凍結(jié)(frozen)。

  1. var fr = {} 
  2. Object.defineProperty(fr, 'fr1', { 
  3.     configurable: true
  4.     writable: false
  5.     value: 'fr1' 
  6. }) 
  7. Object.isFrozen(fr)        // false 
  8. Object.freeze(fr) 
  9. Object.isFrozen(fr)        // true 
  10.  
  11. // 修改已有的屬性會拋出類型錯誤異常 
  12. Object.defineProperty(fr, 'fr1', { 
  13.     writable: true
  14.     value: 'fr11' 
  15. })    // Uncaught TypeError: Cannot redefine property: fr1 
  16.  
  17. // 添加屬性會拋出類型錯誤異常 
  18. Object.defineProperty(fr, 'fr2', { 
  19.     value: 'fr2' 
  20. })    // Uncaught TypeError: Cannot define property:fr2, object is not extensible. 
  21.  
  22. fr.fr1 = 'fr11' 
  23. // 不能修fr1屬性 
  24. fr.fr1            // 'fr1' 
  25. var set = {} 
  26. Object.defineProperty(set'set1', { 
  27.     configurable: true
  28.     value: 'set1' 
  29. }) 
  30. Object.defineProperty(set'set2', { 
  31.     configurable: true
  32.     setfunction(val) { 
  33.         this.set1 = val 
  34.     } 
  35. }) 
  36. Object.isFrozen(set)        // false 
  37. Object.freeze(set
  38. Object.isFrozen(set)        // true 
  39.  
  40. set.set2 = 'set2' 
  41. set.set1                    // 'set1'  

結(jié)語

我對屬性描述符很不熟悉,主要是因為平時用得少。不過最近,開始學(xué)寫一些小的庫(雖然很挫),就感覺屬性描述符有使用的場景了。我暫時能想到的就是將庫對象的一些屬性設(shè)置為只讀,以防止對象的一些屬性被用戶重寫覆蓋了。還有一個用法是在知乎和學(xué)vue的時候知道的,就是通過getter和setter實現(xiàn)“監(jiān)聽”對象屬性的數(shù)據(jù)更新(在這里挖一個坑。后面學(xué)習(xí)一下這種方法,再寫一篇“監(jiān)聽”對象屬性的數(shù)據(jù)更新的文章)。

***,如果大家知道更多屬性描述符的使用后場景,希望大家能在評論區(qū)留下你們的高見。

責(zé)任編輯:龐桂玉 來源: segmentfault
相關(guān)推薦

2012-08-08 10:31:41

IBMdW

2017-02-05 10:06:53

Python黑魔法描述符

2009-07-08 09:46:45

Servlet注釋部署描述符

2025-01-10 15:13:38

2023-04-06 15:22:15

Linux進(jìn)程系統(tǒng)

2019-03-05 22:15:08

BashLinux命令

2009-09-04 14:04:53

C#文檔

2020-02-07 18:16:01

進(jìn)程線程底層原理

2023-12-13 14:01:34

Elasticsea文件描述符操作系統(tǒng)

2021-06-18 06:02:24

內(nèi)核文件傳遞

2021-05-19 14:48:58

Linux文件fd

2009-08-27 10:01:52

C#自動屬性

2009-08-28 09:30:48

C#命名屬性

2009-09-07 15:49:55

C#屬性化的方法

2019-07-05 14:20:45

RPC服務(wù)器模型

2009-12-22 13:49:40

ADO.net屬性

2010-09-15 17:05:33

CSS display

2009-12-28 09:19:21

ADO屬性

2019-07-09 14:30:16

LinuxJava 服務(wù)器

2019-07-09 15:30:31

Linuxulimit文件描述符
點贊
收藏

51CTO技術(shù)棧公眾號