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, enumerable: true, writable: true, value: "Peter" }); alert(person.name); delete person.name; alert(person.name); person.name = "Greg"; alert(person.name);
|
数据属性包含一个数据值的位置。在这个位置可以读取和写入值。数据属性有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, value: "Nicholas" }); var person = {}; Object.defineProperty(person, "name", { configurable: true, value: "Nicholas" });
|
也就是说,可以多次调用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); } }; 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);
|