js 定義屬性 以及 getter 和 setter
阿新 • • 發佈:2019-02-12
今天說一下js 的屬性設定,ES5中定義了兩種屬性,資料屬性和訪問器屬性(getter 和 setter)下面我總結了一些資料屬性 和 訪問器屬性的一些知識點。
一、資料屬性
資料屬性有四個描述其行為的特徵:
- [[Configurable]]: 表示能否被 delete 刪除,預設為 true
- [[Enumerable]]: 表示能否通過 for - in 迴圈返回屬性, 預設為true
- [[Writable]]: 表示能否修改這個屬性的資料值,預設為true
- [[Value]] : 包含這個屬性的值,讀取屬性值時,從這個位置讀,寫入時從這個位置寫入。
注意:要修改屬性的特性,要用ES5的 Object.defineProperty()來定義
該方法有三個引數,第一個為要處理的物件(注意不要帶引號),第二個為要處理的屬性名,第三個為一個物件,用於處理屬性。
例如:
var person = {
_name:"Jhone", // 前面加下橫線 ,下面會講
sex:"man",
age:24,
height:170,
}
person.fun = function () {
console.log("my monthds")
}
Object.defineProperty(person,"name",{
configurable:false, // 設定為通過delete 不能刪除
enumerable:false, // 設定為通過for - in 迴圈不能返回該屬性
writable:false, // 設定為不能修改屬性值
// value: 包含這個屬性的資料值,能寫入,能讀取
});
結果測試:
delete(person.name);
delete(person.sex);
console.log(person.name); // Jhone 說明name不能被delete刪除
console.log(person.sex); // underfind sex屬性被刪除
person.name = 'King';
console.log (person.name); //Jhone 說明name不能被被修改
for(proto in person){
console.log(proto)
}
// 返回的結果中 沒有 name 屬性
二、訪問器屬性
訪問器屬性不包含資料值,他們包含一對 getter 和setter, 不過這兩個函式都不是必須的。在讀取屬性值時,會呼叫getter 函式,這個函式負責返回有效值;在寫入屬性值時,會呼叫seter函式並傳入新值,這個函式負責決定如何處理資料。
- [[Configurable]]: 表示能否被 delete 刪除,預設為 true
- [[Enumerable]]: 表示能否通過 for - in 迴圈返回屬性, 預設為true
- [[Get]]: 在讀取時屬性是呼叫的函式,預設underfind
- [[Set]]: 在寫入取時屬性是呼叫的函式,預設underfind
例如:(還是上面的物件)
Object.defineProperty(person,"age",{
get:function(){
return this._age;
},
set:function(newVlaue){
if(newVlaue > 30){
this.height = 185;
}else{
this.height = 170;
}
}
})
測試結果:
console.log(person.height); //170 沒有設定屬性age(預設170)之前
people.age = 40;
console.log(person.height); // 185 設定age為40後(大於30) height也變化了
get 和 set 方法不是必須的,當你不設定get方法時,
console.log(people.age); // underfind
但你不設定 set 時,對應的屬性是不能夠被寫入的。
三、定義多個屬性
有時候我們想定義多個屬性,ES5 為我們提供了 Object.defineProperties()
方法;
例如:
Object.defineProperties(person,{
_nameTwo:{
value:"LaoZhang"
},
nameTwo:{
get:function(){
return this._name;
},
set:function(newVlaue){
console.log(newVlaue)
}
},
sex:{
set:function(newVlaue){
console.log(newVlaue)
}
}
})
console.log(person.nameTwo) //LaoZhang
person.sex = "man" // man
注意: 屬性用getter 去獲取時,要將屬性前加下劃線 “_”這是js的常用的記號,表示只能通過物件方法訪問。如果你沒有加,那麼 你用get 去獲取屬性時,瀏覽器可能會報錯,但是你在外部訪問時可以不用加, 如 console.log(person.nameTwo)
四、讀取屬性的特性
ES5為我們提供了一個Object.getOwnPropertyDescriptor()
方法來讀取屬性的特性
例如:
var descriptor =Object.getOwnPropertyDescriptor(person,"name");
console.log(descriptor.value) // Jhone
console.log(descriptor.configurable) //true 預設為true,如果你更改了configurable,這裡會有變化
五、定義訪問器的舊有方法
上面所講的一些發方法,一般在IE9+ 能正常實現。要想在更早的IE版本實現要用非標準方法__defineGetter__
和 __defineSetter__
例如:
person.__defineGetter__("name",function(){
return this._name;
})
person.__defineSetter__("name",function(newValue){
console.log(newValue)
})