js面向对象数据属性和访问器属性,定义多个属性及读取属性的特性

2017-9-6 16:14:36 4,532 views
es对对象的定义:无序属性的集合,其属性可以包含基本值,对象或者函数。严格来讲,这就相当于说对象是一组没有特定顺序的值,对象的每个属性或方法都有一个名字,而每个名字都隐射到一个值。

属性类型:

es中有2种属性:数据属性和访问器属性
为了表示特性是内部值,规范把它放入2对方括号中。

1.1数据属性

数据属性包含一个数据值的位置,在这个位置可以读取和写入值。有4个描述其行为的特性。
[[Configurable]]表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,能否把属性修改为访问器属性。默认为true
[[Enumberable]]:表示能否通过for-in循环返回属性。默认为true
[[Writable]]:表示能否修改属性的值。默认为true
[[Value]]:包含这个属性的数据值。读取属性值的时候,从这个位置读;写入属性值的时候,把新值保存在这个位置。默认值为undefined.
var person={
name:"mike";
};

 

对于这样直接在对象上定义的属性,它们的[[Configurable]],[[Enumberable]],[[Writable]]特性都被设置为true,而[[value]]特性被设置为指定的值、
以上的[[Value]]特性将被设置为"mike"

Object.defineProperty()方法:

要修改属性默认的特性 必须使用es的Object.defineProperty()方法接收三个参数:属性所在的对象,属性的名字和一个描述符对象,其中描述符对象的属性必须是configurable,enumerable,writable,value 设置其中的一或多个值,可以修改对应的特性值。
var person={};
Object.defineProperty(person,"name",{
writable:false,//默认为true,能被修改属性的数据值
value:"mike"
});
alert(person.name);//mike
person.name="greg";
alert(person.name);//mike
//这个例子创建了一个名为name的属性,它的值"mike"是只读的。这个属性的值是不可修改的,如果尝试为它指定新值,在非严格模式下,赋值操作将被忽略;在严格模式下执行,会报错

 

报错
类似的规则也适用于不可配置的属性
 
var person={};
Object.defineProperty(person,"name",{
configurable:false,//默认为true,表示可以通过delete来删除属性
value:"mike"
});
alert(person.name);//mike
delete person.name;
alert(person.name);//mike
把configurable设置为false,表示不能从对象中删除属性。

 

如果对这个属性调用delete,则在非严格模式下什么也不会发生,在严格模式下会报错
报错
,一旦把属性定义为不可配置的,就不能把它变回可配置了,此时,再调用Object,defineProperty()方法修改除writable之外的特性,都会导致错误
Object.defineProperty(person,"name",{
configurable:false,
value:"mike"
});
Object.defineProperty(person,"name",{
configurable:true,
value:"mike"
});
//抛出错误

 

报错
在调用Object.defineProperty()方法创建一个新的属性时,如果不指定configurable,enumerable,writable特性的默认值为false。
var person={};
Object.defineProperty(person,"name",{
value:"mike"
});
//会报错,则说明原来的configurable的值为false
Object.defineProperty(person,"name",{
configurable:true,//默认为true,表示可以通过delete来删除属性
value:"mike"
});

 

如果调用Object.defineProperty()方法修改已定义的属性的特性,则无此限制。

1.12访问器属性:

访问器属性不包含数据值:它们包含一对getter和setter函数(这2个函数都不是必须的)在读取访问器属性时,会调用getter(相当于读)函数,这个函数负责返回有效的值;在写入访问器属性时,会调用setter(相当于写)函数并传入新值,这个函数负责决定如何处理数据。访问器属性有4个特性
[[Configurable]]表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,能否把属性修改为访问器属性。默认为true
[[Enumberable]]:表示能否通过for-in循环返回属性。默认为true
[[Get]]:在读取属性时调用的函数,默认为undefined
[[Set]]:在写入属性时调用的函数,默认为undefined
访问器属性不能直接定义,必须使用Object.defineProperty()来定义
var book={
_year:2004,
edition:1
};
Object.defineProperty(book,"year",{
get:function(){
return this._year;
},
set:function(newValue){
if(newValue>2005){
this._year=newValue;
this.edition+=newValue-2004;
}
}
});
book.year=2005;
alert(book.edition);//2

 

_year前面的下划线表示只能通过对象方法访问的属性

1.2定义多个属性

Object.defineProperties()

var book={};
Object.defineProperties(book,{
_year:{
writable:2004
},
edition:{
wriatble:true,
value:1
},year:{
get:function(){
return this._year;
}},
set:function(newValue){
if(newValue)
this._year=newValue;
this.edition+=newValue-2004;
}
});
//与前面的区别就是这里的属性都是同一时间创建的

 

1.3读取属性的特性

Object.getOwnPropertyDescriptor()

es5的Object.getOwnPropertyDescriptor()可以取得给定属性的描述符
:接收2个参数,属性所在的对象和要读取其描述符的属性名称。返回值是一个对象。如果是访问器属性,这个对象的属性有configurable,enumberable,set,get,如果是数据属性,这个对象的属性有configurable,enumberable,writable,value
var book={};
Object.defineProperties(book,{
_year:{
value:2004
},
edition:{
value:1
},year:{
get:function(){
return this._year;
}},
set:function(newValue){
if(newValue>2004)
this._year=newValue;
this.edition+=newValue-2004;
}
});
var descriptor=Object.getOwnPropertyDescriptor(book,"_year");//因为这里的是数据属性,所以返回的对象属性为configurable,enumberable,writable,value
alert(descriptor.value);//2004
alert(descriptor.configurable);//false;
alert(typeof descriptor.get);//undefined
var descriptor=Object.getOwnPropertyDescriptor(book,"year");
alert(descriptor.value);//undefined
alert(descriptor.configurable);//false;
alert(typeof descriptor.get);//function

 

0

分享到微信朋友圈

打开微信,点击底部的“发现”,
使用“扫一扫”即可将网页分享至朋友圈。