日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

详解JavaScript之神奇的Object.defineProperty

發(fā)布時(shí)間:2024/4/13 javascript 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 详解JavaScript之神奇的Object.defineProperty 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

摘要: JavaScript有個(gè)很神奇的Object.defineProperty(),了解一下?

=與Object.defineProperty

為JavaScript對象新增或者修改屬性,有兩種不同方式:直接使用=賦值或者使用Object.defineProperty()定義。如下:

// 示例1 var obj = {};// 直接使用=賦值 obj.a = 1;// 使用Object.defineProperty定義 Object.defineProperty(obj, "b", {value: 2 });console.log(obj) // 打印"{a: 1, b: 2}" 復(fù)制代碼

這樣看兩者似乎沒有區(qū)別,對吧?但是,如果使用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}" 復(fù)制代碼

可知,使用=賦值時(shí),屬性的屬性描述符value是可以修改的,而writable、enumerable和configurable都為true。

而使用Object.defineProperty()定義的屬性的屬性描述符writable、enumerable和configurable默認(rèn)值為false,但是都可以修改。對于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} 復(fù)制代碼// 示例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} 復(fù)制代碼

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} 復(fù)制代碼// 示例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} 復(fù)制代碼

由于writable、enumerable和configurable都是false,導(dǎo)致obj.name屬性不能賦值、不能遍歷而且不能刪除:

// 示例7 var obj = {};Object.defineProperty(obj, "name", {value: "Fundebug" });// writable為false,無法賦值 obj.name = "云麒"; console.log(obj.name); // 打印"Fundebug"// enumerable為false,無法遍歷 console.log(Object.keys(obj)); // 打印"[]"// configurable為false,無法刪除 delete obj.name; console.log(obj.name); // 打印"Fundebug" 復(fù)制代碼

若在嚴(yán)格模式("use strict")下,示例7中的代碼會(huì)報(bào)錯(cuò),下文可見。

writable

writable為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)頁、微信小程序、微信小游戲,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 '#<Object>'” 復(fù)制代碼

writable為true時(shí),屬性可以賦值,這一點(diǎn)讀者不妨自行測試。

enumerable

enumerable為false時(shí),屬性不能遍歷:

// 示例9 "use strict"var obj = {};Object.defineProperty(obj, "name", {value: "Fundebug",writable: true,enumerable: false,configurable: true });console.log(Object.keys(obj)) // 打印"[]" 復(fù)制代碼

enumerable為true時(shí),屬性可以遍歷,這一點(diǎn)讀者不妨自行測試。

configurable

enumerable為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 #<Object>” 復(fù)制代碼

enumerable為true時(shí),屬性可以刪除,這一點(diǎn)讀者不妨自行測試。

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” 復(fù)制代碼

當(dāng)writable或者enumerable為true時(shí),屬性可以重新使用Object.defineProperty()定義,這一點(diǎn)讀者不妨自行測試。

本文所有代碼示例都在Chrome 67上測試。

參考

  • Object.defineProperty()
  • Object.getOwnPropertyDescriptor()
  • StackOverflow: Why can't I redefine a property in a Javascript object?

關(guān)于Fundebug

Fundebug專注于JavaScript、微信小程序、微信小游戲,Node.js和Java實(shí)時(shí)BUG監(jiān)控。 自從2016年雙十一正式上線,Fundebug累計(jì)處理了5億+錯(cuò)誤事件,得到了眾多知名用戶的認(rèn)可。歡迎免費(fèi)試用!

總結(jié)

以上是生活随笔為你收集整理的详解JavaScript之神奇的Object.defineProperty的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。