溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JS屬性的特性是什么

發布時間:2021-11-16 17:38:31 來源:億速云 閱讀:161 作者:柒染 欄目:web開發

這篇文章將為大家詳細講解有關JS屬性的特性是什么,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

概念

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

  • configurable:可配置性,控制著其描述的屬性的修改,表示能否修改屬性的特性,能否把屬性修改為訪問器屬性,或者能否通過delete刪除屬性從而重新定義屬性。默認值為true。

  • enumerable:可枚舉性,表示能否通過for-in遍歷得到屬性。默認值為true。

  • writable:可寫性,表示能否修改屬性的值。默認值為true。

  • value:數據屬性,表示屬性的值。默認值為undefined。

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

  • get:在讀取屬性時調用的函數。只指定get則表示屬性為只讀屬性。默認值為undefined。

  • set:在寫入屬性時調用的函數。只指定set則表示屬性為只寫屬性。默認值為undefined。

使用

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

API 用法

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

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

var hello = {}  Object.defineProperty(hello, 'girl', {     configurable: false,     enumberable: false,     writable: true,     value: 'sexy' })  // 存取器 Object.defineProperty(hello, 'woman', {     configurable: false,     enumberable: false,     get: function() {         return this.girl     },     set: function(val) {         this.girl = val     } })  // 定義多個屬性 Object.defineProperties(hello, {     boy: {         configurable: false,         enumberable: false,         writable: false,         value: 'handsome'     },     man: {         configurable: false,         enumberable: false,         writable: true,         get: function() {             return this.boy         }     } })

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

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

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

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

API 用法

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

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

規則

var rules = {     common: 'test' }

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

Object.defineProperty(rules, 'rule1', {     configurable: false,     enumberable: false })  // 修改configurable會拋出類型錯誤異常 Object.defineProperty(rules, 'rule1', {     configurable: true })    // Uncaught TypeError: Cannot redefine property: rule1  // 修改enumberable不會拋出異常,但enmuberable沒有被修改 Object.defineProperty(rules, 'rule1', {     enumberable: true }) Object.getOwnPropertyDescriptor(rules, 'rule1')    // Object {value: undefined, writable: false, enumerable: false, configurable: false}

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

Object.defineProperty(rules, 'rule2', {     configurable: false,     enumberable: false,     get: function() {         return this.common     },     set: function(val) {         this.common = val     } })  // 修改get或者set方法會拋出類型錯誤異常 Object.defineProperty(rules, 'rule2', {     get: function() {         return this.common + 'rule2'     } })    // Uncaught TypeError: Cannot redefine property: rule2  Object.defineProperty(rules, 'rule2', {     set: function(val) {         this.common = 'rule2'     } })    // Uncaught TypeError: Cannot redefine property: rule2  // 將它轉換為數據屬性同樣會拋出類型錯誤異常 Object.defineProperty(rules, 'rule2', {     value: 'rule2' })    // Uncaught TypeError: Cannot redefine property: rule2

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

Object.defineProperty(rules, 'rule3', {     configurable: false,     writable: false,     value: 'rule3' })  // 修改writable為true會拋出類型錯誤異常 Object.defineProperty(rules, 'rule3', {     writable: true })   Object.defineProperty(rules, 'rule4', {     configurable: false,     writable: true,     value: 'rule4' })  // 可以修改writable為false Object.defineProperty(rules, 'rule4', {     writable: false }) Object.getOwnPropertyDescriptor(rules, 'rule4')    //   Object {value: "rule4", writable: false, enumerable: false, configurable: false}

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

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

Object.defineProperty(rules, 'rule5', {     configurable: false,     writable: false,     value: 'rule5' })  // 修改屬性值會拋出類型錯誤異常 Object.defineProperty(rules, 'rule5', {     value: 'rule55' })    // Uncaught TypeError: Cannot redefine property: rule5  rules.rule5 = 'rule55' // 值沒有被修改,也不會拋出異常 rules.rule5            // 'rule5'   Object.defineProperty(rules, 'rule6', {     configurable: true,     writable: false,     value: 'rule6' })  // 修改屬性值 Object.defineProperty(rules, 'rule6', {     value: 'rule66' }) rules.rule6            // 'rule66'  rules.rule6 = 'rule6' // 值沒有被修改,也不會修改 rules.rule6            // 'rule6'

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

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

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

操作對象可擴展性的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可以將對象轉換為不可擴展。

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

var ex = {} Object.defineProperty(ex, 'ex1', {     configurable: true,     writable: true,     value: 'ex1' }) Object.isExtensible(ex)        // true Object.preventExtensions(ex) Object.isExtensible(ex)        // false  // 可以修改已有的屬性 Object.defineProperty(ex, 'ex1', {     writable: false,     value: 'ex11' }) Object.getOwnPropertyDescriptor(ex, 'ex1')    // Object {value: "ex11", writable: false, enumerable: false, configurable: true}  // 添加屬性會拋出類型錯誤異常 Object.defineProperty(ex, 'ex2', {     value: 'ex2' })    // Uncaught TypeError: Cannot define property:ex2, object is not extensible.

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

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

var se = {} Object.defineProperty(se, 'se1', {     configurable: true,     writable: false,     value: 'se1' }) Object.isSealed(se)        // false Object.seal(se) Object.isSealed(se)        // true  // 修改已有的屬性會拋出類型錯誤異常 Object.defineProperty(se, 'se1', {     writable: true,     value: 'se11' })    // Uncaught TypeError: Cannot redefine property: se1  // 添加屬性會拋出類型錯誤異常 Object.defineProperty(se, 'se2', {     value: 'se2' })    // Uncaught TypeError: Cannot define property:se2, object is not extensible.

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

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

var fr = {} Object.defineProperty(fr, 'fr1', {     configurable: true,     writable: false,     value: 'fr1' }) Object.isFrozen(fr)        // false Object.freeze(fr) Object.isFrozen(fr)        // true  // 修改已有的屬性會拋出類型錯誤異常 Object.defineProperty(fr, 'fr1', {     writable: true,     value: 'fr11' })    // Uncaught TypeError: Cannot redefine property: fr1  // 添加屬性會拋出類型錯誤異常 Object.defineProperty(fr, 'fr2', {     value: 'fr2' })    // Uncaught TypeError: Cannot define property:fr2, object is not extensible.  fr.fr1 = 'fr11' // 不能修fr1屬性 fr.fr1            // 'fr1' var set = {} Object.defineProperty(set, 'set1', {     configurable: true,     value: 'set1' }) Object.defineProperty(set, 'set2', {     configurable: true,     set: function(val) {         this.set1 = val     } }) Object.isFrozen(set)        // false Object.freeze(set) Object.isFrozen(set)        // true  set.set2 = 'set2' set.set1                    // 'set1'

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

關于JS屬性的特性是什么就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女