深圳四站合一網(wǎng)站建設(shè)電話電商網(wǎng)站上信息資源的特點包括
ES6 Object.defineProperty()
用法總結(jié)
Object.defineProperty()
是 ES5 引入的一個方法,ES6 繼續(xù)強化了該方法的使用,它允許我們?yōu)閷ο蟮膶傩远x或修改 屬性描述符。它能夠控制對象屬性的行為,如讀寫權(quán)限、可枚舉性和可配置性。
1. Object.defineProperty()
的語法
Object.defineProperty(obj, prop, descriptor);
obj
:目標對象,想要在該對象上定義或修改屬性。prop
:要定義或修改的屬性的名稱。descriptor
:屬性描述符,描述屬性的特性。描述符是一個對象,包含以下常見屬性:
屬性描述符的常用字段
value
:屬性的值,默認為undefined
。writable
:布爾值,表示屬性值是否可寫(默認為false
)。enumerable
:布爾值,表示屬性是否能被for...in
循環(huán)和Object.keys()
迭代(默認為false
)。configurable
:布爾值,表示屬性是否能被刪除或者修改屬性的特性(默認為false
)。get
:一個函數(shù),作為該屬性的 getter,讀取屬性值時調(diào)用(默認為undefined
)。set
:一個函數(shù),作為該屬性的 setter,寫入屬性值時調(diào)用(默認為undefined
)。
2. 用法和例子
2.1 定義一個屬性并設(shè)置其值
const obj = {};
Object.defineProperty(obj, 'name', {value: 'Alice',writable: true, // 屬性值可寫enumerable: true, // 屬性可枚舉configurable: true // 屬性可配置
});console.log(obj.name); // "Alice"
在這個例子中,我們定義了一個 name
屬性,給它設(shè)置了值 'Alice'
,并且該屬性是可寫、可枚舉和可配置的。
2.2 設(shè)置只讀屬性
const obj = {};
Object.defineProperty(obj, 'name', {value: 'Alice',writable: false // 屬性值不可修改
});console.log(obj.name); // "Alice"
obj.name = 'Bob'; // 嘗試修改
console.log(obj.name); // "Alice" (未修改)
通過將 writable
設(shè)置為 false
,name
屬性變成了只讀屬性,不能修改。
2.3 定義 getter 和 setter
Object.defineProperty()
可以為屬性定義 getter 和 setter,使得可以通過函數(shù)的方式來獲取和設(shè)置屬性值。
const obj = {};
Object.defineProperty(obj, 'name', {get() {return 'Hello, ' + this._name;},set(value) {this._name = value;},enumerable: true,configurable: true
});obj.name = 'Alice';
console.log(obj.name); // "Hello, Alice"
在這個例子中,我們?yōu)?name
屬性定義了一個 getter 和 setter。在設(shè)置屬性時,set
會被調(diào)用,而在獲取屬性時,get
會被調(diào)用。
2.4 定義不可枚舉的屬性
const obj = {};
Object.defineProperty(obj, 'hidden', {value: 'secret',enumerable: false // 屬性不可枚舉
});for (let key in obj) {console.log(key); // 不會輸出 'hidden'
}
console.log(Object.keys(obj)); // [],'hidden' 也不會出現(xiàn)在 Object.keys() 中
在這個例子中,hidden
屬性被定義為不可枚舉,因此它不會出現(xiàn)在 for...in
循環(huán)或者 Object.keys()
的結(jié)果中。
2.5 定義不可配置的屬性
const obj = {};
Object.defineProperty(obj, 'name', {value: 'Alice',configurable: false // 不可刪除或修改
});delete obj.name; // 嘗試刪除
console.log(obj.name); // "Alice" (未刪除)Object.defineProperty(obj, 'name', {value: 'Bob' // 嘗試修改
}); // TypeError: Cannot redefine property: name
通過將 configurable
設(shè)置為 false
,我們使 name
屬性不能被刪除或重新定義。
2.6 定義一個訪問器屬性
const obj = {_age: 25
};Object.defineProperty(obj, 'age', {get() {return this._age;},set(value) {this._age = value >= 0 ? value : 0; // 確保年齡不能為負},enumerable: true,configurable: true
});console.log(obj.age); // 25
obj.age = -5; // 設(shè)置一個負數(shù)
console.log(obj.age); // 0,年齡不允許為負
這個例子演示了通過 get
和 set
來定義訪問器屬性。當試圖設(shè)置一個負數(shù)時,setter 將其轉(zhuǎn)化為 0,確保屬性值始終有效。
3. 使用場景
3.1 實現(xiàn)封裝
Object.defineProperty()
常用于 JavaScript 中模擬封裝,隱藏對象的內(nèi)部數(shù)據(jù),并通過 getter 和 setter 來控制訪問。
const person = {};
let _age = 25;Object.defineProperty(person, 'age', {get() {return _age;},set(value) {if (value < 0) {throw new Error("Age cannot be negative");}_age = value;}
});person.age = 30; // 正常設(shè)置
console.log(person.age); // 30
person.age = -5; // 錯誤:拋出異常
在這個例子中,age
屬性的值被封裝在內(nèi)部變量 _age
中,并且設(shè)置了限制條件,避免年齡為負數(shù)。
3.2 創(chuàng)建常量屬性
如果你想創(chuàng)建一個常量屬性,可以通過 Object.defineProperty()
配置 writable
和 configurable
為 false
,使得該屬性不可更改或刪除。
const obj = {};
Object.defineProperty(obj, 'PI', {value: 3.14159,writable: false,configurable: false
});console.log(obj.PI); // 3.14159
obj.PI = 3.14; // 無效,不會修改
console.log(obj.PI); // 3.14159
通過這種方式,你可以模擬常量,使屬性的值不能被修改。
3.3 定義計算屬性
Object.defineProperty()
可以用來動態(tài)創(chuàng)建和計算屬性,結(jié)合 getter 和 setter 實現(xiàn)靈活的計算。
const obj = {_width: 100,_height: 50
};Object.defineProperty(obj, 'area', {get() {return this._width * this._height;},set(value) {console.log('Area is calculated automatically');},enumerable: true
});console.log(obj.area); // 5000
obj.area = 1000; // 觸發(fā) set(),但不會修改值
在這個例子中,area
是計算屬性,它返回 width
和 height
的乘積,而 set
只是被觸發(fā),但不做實際的修改。
4. 總結(jié)
Object.defineProperty()
使你能夠?qū)ο髮傩缘男袨檫M行精確控制,如定義getter
、setter
,控制是否可寫、是否可枚舉、是否可配置等。- 它常用于實現(xiàn)對象的封裝、屬性校驗、計算屬性和常量屬性等。
- 它允許創(chuàng)建不直接操作對象的內(nèi)部數(shù)據(jù),增加靈活性和安全性。
通過 Object.defineProperty()
,開發(fā)者可以更加靈活地控制對象的行為和屬性特性,滿足更復(fù)雜的編程需求。