ECMAScript属性类型

ECMAScript中有两种属性:数据属性和访问器属性。

1.数据属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var person = {
name: "Nicholas",
age: 29,
job: "Software Engineer",
sayName: function () {
alert(this.name);
}
}
Object.defineProperty(person, "name",
{
configurable: true, //default false
enumerable: true, //default false
writable: true, //default false
value: "Peter" //default undefined
});
alert(person.name);//Peter
delete person.name;//移除属性
alert(person.name);//undefined
person.name = "Greg"; //再添加属性
alert(person.name);//Greg

数据属性包含一个数据值的位置。在这个位置可以读取和写入值。数据属性有4个描述其行为的特性。

  • configurable:表示能否通过delete删除属性从而重新定义属性,能否个性属性的特性,或者能否把属性个性为访问器属性。像前面例子中那样直接在对象上定义的属性,它们的这个特性默认值为true。
  • enumrable:表示能否通过for-in循环返回属性。像前面例子中那样直接在对象上定义属性,它们的这个特性默认值为true。
  • writable:表示能否修改属性的值。像前面例子中那样直接在对象上定义的属性,它们的这个特性默认值为true。
  • value:包含这个属性的数据值。读取属性值的时候,从这个位置读;写入属性值的时候,把新值保存在这个位置。这个特性的默认值为undefined。

注意:如果将configurable设置为false,表示不能从对象中删除属性。如果对这个属性调用delete,则在非严格模式下什么也不会发生,而在严格模式下会导致错误。而且,一旦把属性定义为不可配置的,就不能再把它变回可配置了。此时,再调用Object.defineProperty()方法修改除writable之外的特性,都会导致错误:

1
2
3
4
5
6
7
8
9
10
11
12
13
var person = {};
Object.defineProperty(person, "name",
{
configurable: false, //default true
value: "Nicholas" //default undefined
});
//抛出错误
var person = {};
Object.defineProperty(person, "name",
{
configurable: true, //default true
value: "Nicholas" //default undefined
});

也就是说,可以多次调用Object.defineProperty()方法修改同一个属性,但在把configurable特性设置为false之后就会有限制了。在调用Object.defineProperty()方法时,如果不指定,configurable、enumerable和writable特性的默认值都是为false。多数情况下,可能都没有必要利用Object.defineProperty()方法提供的这些高级功能。不过,理解这些概念对理解JavaScript对象却非常有用。另外建议不要在IE8中使用Object.defineProperty()方法,主要是IE8对这个方法支持实现不彻底。

2.访问器属性

访问器属性不包含数据值;它们包含一对儿getter和setter函数(不过,这两个函数都不是必需的)。在读取访问器属性时,会调用getter函数,这个函数负责返回有效的值;在写入访问器属性时,会调用setter函数并传入新值,这个函数负责决定如何处理数据。访问器属性除拥有get和set特性外,还与上面的数据属性一样也拥有configurable和enumerable特性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var person = {
name: "Nicholas",
_born: "2009-01-01",
age: 29,
job: "Software Engineer",
sayName: function () {
alert(this.name);
}
};
//设置born访问器属性,born提供外部访问使用
Object.defineProperty(person, "born",
{
get: function () {
return this._born;
},
set: function (newValue) {
var date = new Date(newValue);
if (date.getTime() <= new Date().getTime()) {
this._born = newValue;
} else {
date = new Date();
this._born = date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate();
}
}
});
person.born = "2015-01-01";
alert(person.born);

3.定义多个属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var person = {};
Object.defineProperties(person,
{
_born:{value:'2008-01-01'},
age:{value:18},
born:{ get: function () {
return this._born;
},
set: function (newValue) {
var date = new Date(newValue);
if (date.getTime() <= new Date().getTime()) {
this._born = newValue;
} else {
date = new Date();
this._born = date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate();
}
}
}
});
person.born = "2015-01-01";
alert(person.born);
文章目录
  1. 1. 1.数据属性
  2. 2. 2.访问器属性
  3. 3. 3.定义多个属性