摘要:與當(dāng)與同時(shí)為時(shí),屬性不能重新使用定義,嚴(yán)格模式下會(huì)報(bào)錯(cuò)示例云麒報(bào)錯(cuò)當(dāng)或者為時(shí),屬性可以重新使用定義,這一點(diǎn)讀者不妨自行測(cè)試。
摘要: JavaScript有個(gè)很神奇的Object.defineProperty(),了解一下?
=與Object.defineProperty為JavaScript對(duì)象新增或者修改屬性,有兩種不同方式:直接使用=賦值或者使用Object.defineProperty()定義。如下:
// 示例1 var obj = {}; // 直接使用=賦值 obj.a = 1; // 使用Object.defineProperty定義 Object.defineProperty(obj, "b", { value: 2 }); console.log(obj) // 打印"{a: 1, b: 2}"
這樣看兩者似乎沒(méi)有區(qū)別,對(duì)吧?但是,如果使用Object.getOwnPropertyDescriptor()查看obj.a與obj.b的屬性的描述描述符(property descriptor)時(shí),會(huì)發(fā)現(xiàn)=與Object.defineProperty并不一樣:
// 示例2 var obj = {}; obj.a = 1; Object.defineProperty(obj, "b", { value: 2 }); console.log(Object.getOwnPropertyDescriptor(obj, "a")); // 打印"{value: 1, writable: true, enumerable: true, configurable: true}" console.log(Object.getOwnPropertyDescriptor(obj, "b")); // 打印"{value: 2, writable: false, enumerable: false, configurable: false}"
可知,使用=賦值時(shí),屬性的屬性描述符value是可以修改的,而writable、enumerable和configurable都為true。
而使用Object.defineProperty()定義的屬性的屬性描述符writable、enumerable和configurable默認(rèn)值為false,但是都可以修改。對(duì)于writable、enumerable和configurable的含義,從名字就不難猜中,后文也會(huì)詳細(xì)介紹。
使用=賦值,等價(jià)于使用Object.defineProperty()定義時(shí),同時(shí)將writable、enumerable和configurable設(shè)為true。代碼示例3和4是等價(jià)的:
// 示例3 var obj = {}; obj.name = "Fundebug"; console.log(Object.getOwnPropertyDescriptor(obj, "name")); // 打印{value: "Fundebug", writable: true, enumerable: true, configurable: true}
// 示例4 var obj = {}; Object.defineProperty(obj, "name", { value: "Fundebug", writable: true, enumerable: true, configurable: true }); console.log(Object.getOwnPropertyDescriptor(obj, "name")); // 打印{value: "Fundebug", writable: true, enumerable: true, configurable: true}Object.defineProperty()
使用Object.defineProperty()定義時(shí)若只定義value,則writable、enumerable和configurable默認(rèn)值為false。代碼示例5和6是等價(jià)的:
// 示例5 var obj = {}; Object.defineProperty(obj, "name", { value: "Fundebug" }); console.log(Object.getOwnPropertyDescriptor(obj, "name")); // 打印{value: "Fundebug", writable: false, enumerable: false, configurable: false}
// 示例6 var obj = {}; Object.defineProperty(obj, "name", { value: "Fundebug", writable: false, enumerable: false, configurable: false }); console.log(Object.getOwnPropertyDescriptor(obj, "name")); // 打印{value: "Fundebug", writable: false, enumerable: false, configurable: false}
由于writable、enumerable和configurable都是false,導(dǎo)致obj.name屬性不能賦值、不能遍歷而且不能刪除:
// 示例7 var obj = {}; Object.defineProperty(obj, "name", { value: "Fundebug" }); // writable為false,無(wú)法賦值 obj.name = "云麒"; console.log(obj.name); // 打印"Fundebug" // enumerable為false,無(wú)法遍歷 console.log(Object.keys(obj)); // 打印"[]" // configurable為false,無(wú)法刪除 delete obj.name; console.log(obj.name); // 打印"Fundebug"
若在嚴(yán)格模式("use strict")下,示例7中的代碼會(huì)報(bào)錯(cuò),下文可見(jiàn)。
writablewritable為false時(shí),屬性不能再次賦值,嚴(yán)格模式下會(huì)報(bào)錯(cuò)“Cannot assign to read only property”(如果你希望實(shí)時(shí)監(jiān)控類似的應(yīng)用錯(cuò)誤的話,歡迎免費(fèi)試用Fundebug,我們支持前端網(wǎng)頁(yè)、微信小程序、微信小游戲,Node.js以及Java錯(cuò)誤監(jiān)控!):
// 示例8 "use strict" var obj = {}; Object.defineProperty(obj, "name", { value: "Fundebug", writable: false, enumerable: true, configurable: true }); obj.name = "云麒"; // 報(bào)錯(cuò)“Uncaught TypeError: Cannot assign to read only property "name" of object "#
writable為true時(shí),屬性可以賦值,這一點(diǎn)讀者不妨自行測(cè)試。
enumerableenumerable為false時(shí),屬性不能遍歷:
// 示例9 "use strict" var obj = {}; Object.defineProperty(obj, "name", { value: "Fundebug", writable: true, enumerable: false, configurable: true }); console.log(Object.keys(obj)) // 打印"[]"
enumerable為true時(shí),屬性可以遍歷,這一點(diǎn)讀者不妨自行測(cè)試。
configurableenumerable為false時(shí),屬性不能刪除,嚴(yán)格模式下會(huì)報(bào)錯(cuò)“Cannot delete property”:
// 示例10 "use strict" var obj = {}; Object.defineProperty(obj, "name", { value: "Fundebug", writable: true, enumerable: true, configurable: false }); delete obj.name // 報(bào)錯(cuò)“Uncaught TypeError: Cannot delete property "name" of #
enumerable為true時(shí),屬性可以刪除,這一點(diǎn)讀者不妨自行測(cè)試。
writable與configurable當(dāng)writable與enumerable同時(shí)為false時(shí),屬性不能重新使用Object.defineProperty()定義,嚴(yán)格模式下會(huì)報(bào)錯(cuò)“Cannot redefine property”:
// 示例11 "use strict" var obj = {}; Object.defineProperty(obj, "name", { value: "Fundebug", writable: false, configurable: false }) Object.defineProperty(obj, "name", { value: "云麒" }) // 報(bào)錯(cuò)“Uncaught TypeError: Cannot redefine property: name”
當(dāng)writable或者enumerable為true時(shí),屬性可以重新使用Object.defineProperty()定義,這一點(diǎn)讀者不妨自行測(cè)試。
本文所有代碼示例都在Chrome 67上測(cè)試。
參考Object.defineProperty()
Object.getOwnPropertyDescriptor()
StackOverflow: Why can"t I redefine a property in a Javascript object?
關(guān)于FundebugFundebug專注于JavaScript、微信小程序、微信小游戲、支付寶小程序、React Native、Node.js和Java實(shí)時(shí)BUG監(jiān)控。 自從2016年雙十一正式上線,F(xiàn)undebug累計(jì)處理了6億+錯(cuò)誤事件,得到了Google、360、金山軟件等眾多知名用戶的認(rèn)可。歡迎免費(fèi)試用!
版權(quán)聲明轉(zhuǎn)載時(shí)請(qǐng)注明作者Fundebug以及本文地址:
https://blog.fundebug.com/2018/07/05/javascript-object-defineproperty/
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/110146.html
摘要:我們通過(guò)一個(gè)簡(jiǎn)單的例子與圖示,來(lái)了解構(gòu)造函數(shù),實(shí)例與原型三者之間的關(guān)系。而原型對(duì)象的指向構(gòu)造函數(shù)。于是根據(jù)構(gòu)造函數(shù)與原型的特性,我們就可以將在構(gòu)造函數(shù)中,通過(guò)聲明的屬性與方法稱為私有變量與方法,它們被當(dāng)前被某一個(gè)實(shí)例對(duì)象所獨(dú)有。 showImg(https://segmentfault.com/img/remote/1460000008593382); 如果要我總結(jié)一下學(xué)習(xí)前端以來(lái)我遇...
摘要:屬性描述符升級(jí)打怪必備技能對(duì)象有自己的屬性和方法,對(duì)于我們對(duì)象的屬性來(lái)講,屬性還有自己的屬性,又稱為屬性描述符。這個(gè)方法接受三個(gè)參數(shù),第一個(gè)是指定的對(duì)象,第二個(gè)是指定的對(duì)象參數(shù),第三個(gè)當(dāng)然是要修改的屬性描述符了。 對(duì)象的聲明有倆種: 字面量 通過(guò)new一個(gè)構(gòu)造函數(shù)Object 兩者唯一的區(qū)別就是,字面量形式,可以一次賦值多個(gè),通過(guò)new Object就得一個(gè)一個(gè)賦值 數(shù)據(jù)類型 ...
摘要:是通過(guò)它實(shí)現(xiàn)雙向綁定的。。而且也被草案發(fā)起人撤回了。。傳入?yún)?shù)第一個(gè)參數(shù)目標(biāo)對(duì)象第二個(gè)參數(shù)需要定義的屬性或方法的名字。第三個(gè)參數(shù)目標(biāo)屬性所擁有的特性。打印沒(méi)有錯(cuò)誤拋出在嚴(yán)格模式下會(huì)拋出,即使之前已經(jīng)有相同的值打印,賦值不起作用。 這個(gè)方法了不起啊。。vue.js是通過(guò)它實(shí)現(xiàn)雙向綁定的。。而且Object.observe也被草案發(fā)起人撤回了。。所以defineProperty更有必要了解...
摘要:創(chuàng)建對(duì)象創(chuàng)建一個(gè)普通對(duì)象創(chuàng)建一個(gè)沒(méi)有原型的新對(duì)象不繼承任何屬性和方法返回對(duì)象中可枚舉的自我屬性的名稱的數(shù)組返回對(duì)象中所有自我屬性的名稱的數(shù)組屬性的特性屬性有兩種特性數(shù)據(jù)屬性和存取器屬性數(shù)據(jù)屬性存取器屬性可以獲得某個(gè)對(duì)象特定自有屬性的屬性描述 Object.create(o) 創(chuàng)建對(duì)象 Object.create({x: 1}) //創(chuàng)建一個(gè)普通對(duì)象 Object.create(null...
摘要:和的作用一樣,區(qū)別在于寫法語(yǔ)法對(duì)象對(duì)象作用判斷對(duì)象是否在對(duì)象的原型鏈上語(yǔ)法對(duì)象構(gòu)造函數(shù)作用判斷構(gòu)造函數(shù)的屬性是否在對(duì)象的原型鏈上,如果在,就返回屬性是否可枚舉用于檢查給定的屬性是否能夠使用語(yǔ)句。 ## javascript對(duì)象原型成員詳解 ## ECMAScript 中的對(duì)象就是一組數(shù)據(jù)和功能的集合,對(duì)象可以通過(guò) new 操作符后跟要?jiǎng)?chuàng)建的對(duì)象名稱來(lái)...
閱讀 3080·2021-10-12 10:12
閱讀 5475·2021-09-26 10:20
閱讀 1539·2021-07-26 23:38
閱讀 2834·2019-08-30 15:54
閱讀 1665·2019-08-30 13:45
閱讀 1984·2019-08-30 11:23
閱讀 3118·2019-08-29 13:49
閱讀 904·2019-08-26 18:23