首頁 >web前端 >js教程 >JavaScript中Object.defineProperty()方法的解析

JavaScript中Object.defineProperty()方法的解析

不言
不言原創
2018-07-20 10:54:201473瀏覽

這篇文章要跟大家介紹的內容是關於JavaScript中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}"

這樣看兩者似乎沒有差別,對吧?但是,如果使用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()

使用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

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

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時,屬性可以遍歷,這一點讀者不妨自行測試。

configurable

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與configurable

當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上測試。

相關推薦:

js中類別的擴充與物件導向的技術解析

angularjs關於頁面範本清除的使用方法

以上是JavaScript中Object.defineProperty()方法的解析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn