淺談JavaScript 數(shù)據(jù)屬性和訪問器屬性
在JavaScript中對象被定義為"無序?qū)傩缘募希鋵傩钥梢园局?、對象或函?shù)。"通俗點講,我們可以把對象理解為一組一組的名值對,其中值可以是數(shù)據(jù)或函數(shù)。
創(chuàng)建自定義對象通常有兩種方法,第一種就是創(chuàng)建一個Object的實例,然后再為其添加屬性和方法,例如:
var person = new Object();
person.name = "Scott";
person.age = 24;
person.sayName = function(){
alert(person.name);
}
第二種方法即對象字面量法,一般推薦使用這種方法創(chuàng)建對象,例如:
var person = {
name: "Scott",
age: 24,
sayName: function(){
alert(this.name);
}
}
屬性類型
JavaScript中定義了兩種不同的屬性:數(shù)據(jù)屬性和訪問器屬性。數(shù)據(jù)屬性一般用于存儲數(shù)據(jù)數(shù)值,而訪問器屬性一般進行g(shù)et/set操作,不能直接存儲數(shù)據(jù)數(shù)值。在ES5中,我們?yōu)榱嗣枋鰧傩?property)的各種特征,定義了特性(attribute)。在JavaScript中不能直接訪問特性,我們把它放在兩對方括號中,例如[[Enumerable]]。
•數(shù)據(jù)屬性
數(shù)據(jù)屬性主要有四個特性描述其行為:
1.[[Configurable]]:默認為true。表示能否通過delete刪除屬性從而重新定義屬性,能否修改屬性特性,或者能否把屬性修改為訪問器屬性;
2.[[Enumerable]]:默認為true。表示能否通過for-in循環(huán)返回屬性;
3.[[Writable]]:默認為true。表示能否修改屬性的值。
4.[[Value]]:默認值為undefined。表示包含屬性的數(shù)據(jù)值。讀寫屬性值都從這個位置進行。
對于上面直接在person對象上定義的屬性,它們的[[Configurable]]、[[Enumerable]]、[[Writable]]特性都被默認設(shè)置為true,而[[Value]]特性被設(shè)置為特定值。如果想要修改屬性默認的特性,可以使用ES5提供的Object.defineProperty()方法,這個方法接收三個參數(shù):屬性所在對象、屬性的名字和一個描述符對象。描述符對象只能包含上述四個特性的一個或多個。例子如下:
var person = {
name: "Scott"
}
Object.defineProperty(person,"name",{
writable:false;
})
console.log(person.name); //"Scott"
person.name = "Evan";
console.log(person.name); //"Scott"
將person對象name屬性的特性writable設(shè)置為false,此屬性的值為不可修改的,因此對該屬性的復制操作會直接忽略。
var person = {
name: "Scott"
}
Object.defineProperty(person,"name",{
configurable:false;
})
console.log(person.name); //"Scott"
delete person.name;
console.log(person.name); //"Scott"
可以看到,當把name屬性的特性值configurable設(shè)置為false之后,就表示不能從對象中刪除屬性。但需要注意的是,當把屬性定義為不可配置之后,就不能把它變回可配置的了。此時修改除writable之外的其它特性都會報錯,例如:
var person = {
name: "Scott"
}
Object.defineProperty(person,"name",{
configurable:false;
})
Object.defineProperty(person,"name",{
configurable:true; //此處會拋出錯誤
})
也就是說,在把configurable特性修改為false之后,再修改其它特性就會有限制存在。
•訪問器屬性
訪問器屬性不包含數(shù)據(jù)值。它包含一對getter和setter函數(shù)。當讀取訪問器屬性時,會調(diào)用getter函數(shù)并返回有效值;當寫入訪問器屬性時,會調(diào)用setter函數(shù)并傳入新值,setter函數(shù)負責處理數(shù)據(jù)。該屬性有四個特性:
1.[[Configurable]]:默認為true。表示能否通過delete刪除屬性從而重新定義屬性,能否修改屬性特性,或者能否把屬性修改為訪問器屬性;
2.[[Enumerable]]:默認為true。表示能否通過for-in循環(huán)返回屬性;
3.[[Get]]:讀取屬性時調(diào)用的函數(shù),默認為undefined;
4.[[Set]]:寫入屬性時調(diào)用的函數(shù),默認為undefined。
訪問器屬性不能直接定義,必須通過Object.defineProperty()函數(shù)定義,例如:
var person = {
_name: "Scott",
_age: 24,
_tel: 86247
};
//name屬性為只讀的
Object.defineProperty(person,"name",{
get: function(){
return this._name;
}
});
//age屬性為只寫不可讀的
Object.defineProperty(person,"age",{
set: function(p){
this._age = p;
}
});
//tel屬性為可讀可寫的
Object.defineProperty(person,"tel",{
get:function(){
return this._tel;
},
set: function(p){
this._tel = p;
}
});
console.log(person.name); //"Scott"
person.name = "Evan";
console.log(person.name); //"Scott",對name屬性的修改無效
console.log(person.age); //undefined,不可讀屬性
person.age = 25;
console.log(person._age); //25,已經(jīng)修改
console.log(person.tel); //"86247",可讀屬性
person.tel = "13975";
console.log(person.tel); //"13975",可以修改
屬性前面的下劃線表示只能通過對象方法訪問的屬性。當我們使用person.name時實際上調(diào)用的是name屬性的getter函數(shù),為person.name賦值時調(diào)用的是name屬性的setter函數(shù),這樣屬性和訪問器之間的關(guān)系就很清晰了。
定義多個屬性
實際上ES5為我們提供了為一個對象定義多個屬性的方法,即Object.defineProperties(),該函數(shù)接收兩個參數(shù),屬性所在的對象以及需要修改的屬性及其描述符對象組成的對象,例如把上邊的例子修改為一次性定義多個屬性,如下:
var person = {
_name: "Scott",
_age: 24,
_tel: 86247
};
Object.defineProperties(person,{
name:{
get: function(){
return this._name;
}
},
age:{
set: function(p){
this._age = p;
}
},
tel:{
get:function(){
return this._tel;
},
set: function(p){
this._tel = p;
}
}
});
讀取屬性的特性
ES5提供了Object.getOwnPropertyDescripter()方法來獲取給定屬性的描述符。該方法接收兩個參數(shù):屬性所在的對象和要讀取其描述符的屬性名稱。結(jié)果會返回一個對象,如果是訪問器屬性,返回的對象有configuable、enumerable、get和set;如果是數(shù)據(jù)屬性,這個返回對象的屬性包括configuable、enumerable、writable和value。對于上面的例如,使用如下:
var person = {
_name: "Scott",
_age: 24,
_tel: 86247
};
Object.defineProperties(person,{
name:{
get: function(){
return this._name;
}
},
age:{
set: function(p){
this._age = p;
}
},
tel:{
get:function(){
return this._tel;
},
set: function(p){
this._tel = p;
}
}
});
var descripter = Object.getOwnPropertyDescripter(person,"tel");
console.log(descripter.value); //undefined
console.log(descripter.enumerable); //false
console.log(typeof descripter.get); //"function"
上面的代碼中獲取了person對象的tel屬性,由于其是一個訪問器屬性,所以其value為undefined,enumerable為false,而get為指向getter函數(shù)的一個指針。
以上這篇淺談JavaScript 數(shù)據(jù)屬性和訪問器屬性就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
JavaScript中SetInterval與setTimeout的用法詳解
在寫H5游戲時經(jīng)常需要使用定時刷新頁面實現(xiàn)動畫效果,比較常用即setTimeout()以及setInterval(),但是大家對SetInterval與setTimeout的用法了解嗎,下面通過本文給大家詳解js中SetInterval與setTimeout的用法,需要的朋友參考下2015-11-11
JS中的兩種數(shù)據(jù)類型及實現(xiàn)引用類型的深拷貝的方法
大家都知道在JS中數(shù)據(jù)類型按照訪問方式和存儲方式的不同可分為基本類型和引用類型。這篇文章主要介紹了JS中的兩種數(shù)據(jù)類型以及實現(xiàn)引用類型的深拷貝 ,需要的朋友可以參考下2018-08-08
javascript動態(tài)創(chuàng)建表格及添加數(shù)據(jù)實例詳解
這篇文章主要介紹了javascript動態(tài)創(chuàng)建表格及添加數(shù)據(jù),以實例形式分析了javascript動態(tài)創(chuàng)建表格的常用方法,包括不兼容IE6與兼容IE6的實現(xiàn)方法,非常具有實用價值,需要的朋友可以參考下2015-05-05
Javascript中匿名函數(shù)的多種調(diào)用方式總結(jié)
這篇文章主要是對Javascript中匿名函數(shù)的多種調(diào)用方式進行了詳細的總結(jié)介紹。需要的朋友可以過來參考下,希望對大家有所幫助2013-12-12

