這篇文章要跟大家介紹的內容是關於JavaScript中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}"
這樣看兩者似乎沒有差別,對吧?但是,如果使用Object.getOwnPropertyDescriptor()查看obj.a與obj.b的屬性的描述描述符(property descriptor)時,會發現=與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}"
可知,使用=賦值時,屬性的屬性描述符value是可以修改的,而writable、enumerable和configurable都為true。
而使用Object.defineProperty()定義的屬性的屬性描述子writable、enumerable和configurable預設值為false,但都可以修改。對於writable、enumerable和configurable的意思,從名字就不難猜中,後文也會詳細介紹。
使用=賦值,等價於使用Object.defineProperty()定義時,同時將writable、enumerable和configurable設為true。程式碼範例3和4是等價的:
// 示例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()定義時若只定義value,則writable、enumerable和configurable預設值為false。程式碼範例5和6是等價的:
// 示例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,導致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"
若在嚴格模式("use strict")下,範例7中的程式碼會報錯,下文可見。
writable為false時,屬性不能再賦值,嚴格模式下會報錯「Cannot assign to read only property」(如果你希望即時監控類似的應用錯誤的話,歡迎免費試用Fundebug,我們支援前端網頁、微信小程式、微信小遊戲,Node.js以及Java錯誤監控!):
// 示例8 "use strict" var obj = {}; Object.defineProperty(obj, "name", { value: "Fundebug", writable: false, enumerable: true, configurable: true }); obj.name = "云麒"; // 报错“Uncaught TypeError: Cannot assign to read only property 'name' of object '#<Object>'”
writable為true時,屬性可以賦值,這一點讀者不妨自行測試。
enumerable為false時,屬性不能遍歷:
// 示例9 "use strict" var obj = {}; Object.defineProperty(obj, "name", { value: "Fundebug", writable: true, enumerable: false, configurable: true }); console.log(Object.keys(obj)) // 打印"[]"
enumerable為true時,屬性可以遍歷,這一點讀者不妨自行測試。
enumerable為false時,屬性無法刪除,嚴格模式下會錯誤「Cannot delete property」:
// 示例10 "use strict" var obj = {}; Object.defineProperty(obj, "name", { value: "Fundebug", writable: true, enumerable: true, configurable: false }); delete obj.name // 报错“Uncaught TypeError: Cannot delete property 'name' of #<Object>”
enumerable為true時,屬性可以刪除,這一點讀者不妨自行測試。
當writable與enumerable同時為false時,屬性無法重新使用Object.defineProperty()定義,嚴格模式下會報錯「Cannot redefine property」:
// 示例11 "use strict" var obj = {}; Object.defineProperty(obj, "name", { value: "Fundebug", writable: false, configurable: false }) Object.defineProperty(obj, "name", { value: "云麒" }) // 报错“Uncaught TypeError: Cannot redefine property: name”
當writable或enumerable為true時,屬性可以重新使用Object.defineProperty()定義,這一點讀者不妨自行測試。
本文所有程式碼範例都在Chrome 67上測試。
相關推薦:
以上是JavaScript中Object.defineProperty()方法的解析的詳細內容。更多資訊請關注PHP中文網其他相關文章!