面向对象--内部属性类型
js中的對(duì)象有一些內(nèi)部才用的特性,這些特性是為了實(shí)現(xiàn)javascript引擎用的,因此在javascript中不能直接訪問(wèn)它們。
有兩種屬性:數(shù)據(jù)屬性 && 訪問(wèn)器屬性
數(shù)據(jù)屬性
- [[ configurable ]]: 表示能否通過(guò) delete 刪除屬性然后重新定義屬性,能否修改屬性的特性,或者能否把屬性修改為訪問(wèn)器屬性。直接在對(duì)象上定義的屬性,它們這個(gè)特性的默認(rèn)值為 true;
- [[ enumerable ]]: 表示能否通過(guò) for-in 循環(huán)返回屬性。直接在對(duì)象上定義的屬性,它們這個(gè)特性的默認(rèn)值為 true;
- [[ writable ]]: 表示能否修改屬性的值。直接在對(duì)象上定義的屬性,它們這個(gè)特性的默認(rèn)值為 true;
- [[ value ]]: 包含這個(gè)屬性的數(shù)據(jù)值。讀取屬性值的時(shí)候,從這個(gè)位置讀;寫入屬性的時(shí)候,把新值保存在這個(gè)位置。這個(gè)特性的默認(rèn)值為 undefined ;
要修改屬性的特性,必須使用 ES5 的 Object.definePrototype() 方法。這個(gè)方法接受三個(gè)參數(shù):
1、屬性所在的對(duì)象。
2、屬性的名字。
3、描述符對(duì)象。屬性必須是:configurable、enumerable、writable、value中的一個(gè)或多個(gè)。
var obj = {}; Object.defineProperty(obj, 'name', {writable: false, // 不能修改值value: '張三' }) console.log(obj.name); // 張三 obj.name = '李四'; console.log(obj.name); // 張三, writable設(shè)為 false 后,值就沒(méi)法修改了。 var person = {name: '李四',age: 24 } delete person.name; console.log(person); // {age: 24} Object.defineProperty(person, 'age', {configurable: false }) delete person.age; console.log(person);// {age: 24} configurable特性設(shè)為 false 后,就沒(méi)法使用 delete 刪除了。 復(fù)制代碼把 configurable 設(shè)置為 false 后,就不能用 delete 刪除屬性,而且,也不能修改 除 writable 外的特性。
var obj = {}; Object.defineProperty(obj, "name", {configurable: false,value: '張三' })// 會(huì)拋出錯(cuò)誤 Object.defineProperty(obj, "name", {configurable: true,value: '張三' }) 復(fù)制代碼也就是說(shuō),可以多次調(diào)用 Object.defineProperty()方法修改同一個(gè)屬性,但在把 configurable特性設(shè)置為 false 后就有限制了。在調(diào)用Object.defineProperty()方法創(chuàng)建一個(gè)新的屬性時(shí),如果不指定,configurable、enumerable、writable 特性的默認(rèn)值都是 false,如果是修改已存在的屬性,就不會(huì)有這個(gè)限制。
訪問(wèn)器屬性
訪問(wèn)器屬性沒(méi)有數(shù)據(jù)值,有g(shù)et、 set函數(shù)。讀取訪問(wèn)器屬性時(shí),會(huì)調(diào)用 get函數(shù),在寫入值時(shí)會(huì)調(diào)用set函數(shù)。
訪問(wèn)器屬性有如下四個(gè)特性:
- [[ configurable ]]: 表示能否通過(guò) delete 刪除屬性,從而重新定義屬性。能否修改屬性的特性,或者能否把屬性修改為數(shù)據(jù)屬性。直接在對(duì)象上定義的屬性,它們這個(gè)特性的默認(rèn)值為 true;
- [[ enumerable ]]: 表示能否通過(guò) for-in 循環(huán)返回屬性。直接在對(duì)象上定義的屬性,它們這個(gè)特性的默認(rèn)值為 true;
- [[ get ]]: 讀取屬性時(shí),調(diào)用的函數(shù)。默認(rèn)值為 undefined;
- [[ set ]]: 寫入屬性時(shí),調(diào)用的函數(shù)。默認(rèn)值為 undefined;
訪問(wèn)器屬性不能直接定義,必須通過(guò)Object.defintProperty()來(lái)定義。
let person = {name: '張三',age: 25 } Object.defineProperty(person, 'oldAge', {get: function () {return this.age + 1;},set: function (newValue) {if (newValue > this.age) {this.age = newValue - 1;this.name = '李四'} else {this.age = newValue + 1;this.name = "王五"}} })person.oldAge = 28; console.log(person); // {name: '李四', age: 27}; 復(fù)制代碼上面定義了一個(gè) person 對(duì)象。默認(rèn)有兩個(gè)屬性, "name"、"age"。新增了一個(gè)訪問(wèn)器屬性 "oldAge"。它包含了兩個(gè)函數(shù)。 get 函數(shù)用來(lái)返回值。set函數(shù),當(dāng)為 "oldAge"寫入值的時(shí)候,會(huì)調(diào)用。把 oldAge 設(shè)置為 27 后,調(diào)用 set 函數(shù),改變了 person 對(duì)象的 "name" 和 "age" 屬性值。
不一定非要同時(shí)指定 set、get函數(shù)。只指定 get函數(shù),意味著屬性不能寫,嚴(yán)格模式會(huì)報(bào)錯(cuò)。只指定了set函數(shù),屬性就不能讀取,嚴(yán)格模式同樣會(huì)報(bào)錯(cuò)。
定義多個(gè)屬性
ES5 定義了一個(gè) Object.defineProperties() 方法,可以通過(guò)描述符一次定義多個(gè)屬性。這個(gè)方法,接受兩個(gè)對(duì)象參數(shù):第一個(gè)是要添加和修改其屬性的對(duì)象,第二個(gè)就是要設(shè)置的屬性的對(duì)象。
let car = {}; Object.defineProperties(car, {createYear: {writable: false,value: 2010},color: {writable: true,value: 'block'},severalYear: {get: function () {return parseInt(new Date().getFullYear()) - this.createYear},set: function (newValue) {if (newValue > 2010) {this.color = 'red';}} } }) console.log(car.createYear); // 2010 console.log(car.color); // 'block' console.log(car.severalYear); // 8 car.severalYear = 2015; console.log(car.createYear); // 2010 console.log(car.color); // 'red' console.log(car.severalYear); // 8 復(fù)制代碼需要注意的是:雖然我們?cè)O(shè)置 car.severalYear = 2015. 但是car.severalYear的值并沒(méi)有改變。因?yàn)闉樵L問(wèn)器屬性寫入值的時(shí)候,只是會(huì)去執(zhí)行 set 函數(shù),而真實(shí)的值只能是通過(guò)get函數(shù)返回。
讀取屬性的特性
使用 ES5 的 Object.getOwnPropertyDescriptor()方法,可以取得給定屬性的描述符。這個(gè)方法接受兩個(gè)參數(shù):
1、屬性所在的對(duì)象。
2、屬性名稱。
返回值是一個(gè)對(duì)象,如果是數(shù)據(jù)屬性,這個(gè)對(duì)象的屬性有:configurable、enumerable、writable、value。 如果是一個(gè)訪問(wèn)器屬性,對(duì)象的屬性有:configurable、enumerable、get、set。
let car = {}; Object.defineProperties(car, {createYear: {writable: false,value: 2010},color: {writable: true,value: 'block'},severalYear: {get: function () {return parseInt(new Date().getFullYear()) - this.createYear},set: function (newValue) {if (newValue > 2010) {this.color = 'red';}} } })let descriptpor = Object.getOwnPropertyDescriptor(car, "createYear"); console.log(descriptpor); // { value: 2010, // writable: false, // enumerable: false, // configurable: false }let fangdescriptpor = Object.getOwnPropertyDescriptor(car, "severalYear"); console.log(fangdescriptpor); // 看下圖 復(fù)制代碼在 JavaScript 中可以針對(duì)任何對(duì)象-----包括 DOM 和 BOM 對(duì)象使用 Object.getOwnPropertyDescriptor()方法。
轉(zhuǎn)載于:https://juejin.im/post/5abce33e6fb9a028cf328eb2
總結(jié)
以上是生活随笔為你收集整理的面向对象--内部属性类型的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Java 内部类示例
- 下一篇: 1968. [AHOI2005]约数研究