ECMAScript 中有两种属性:数据属性和访问器属性
一 属性类型
1.数据属性。数据属性有4个描述其行为的特性
[[Configurable]]表示能否通过delete删除属性从而重新定义属性; 能否修改属性; 能否把属性修改为访问器属性。
[[Enumerable]] 表示是否能通过for-in循环进行枚举。
[[Writable]] 表示能否修改属性的值
[[value]] 包含这个属性的值。读取和写入属性值,都是从这个位置来操作
对象字面量初始化时定义的属性,这些特性默认都是为true。
Object.defineProperty(object, property, descriptor) //descriptor 称为描述符对象
var person = {}; Object.defineProperty(person, "name", { writable: false, //将对象属性设置为属性值不可修改 value: "Nicholas" //初始化属性name的值。因为包含value特性,因此"name"属性是数值属性 }); alert(person.name); // Nicholas person.name = "Greg"; alert(person.name); // Nicholas
[[Configurable]] 特性如果设置为false,则不能使用delete删除这个属性。并且只能修改writable这个特性,其他的属性都将不能再修改。
2.访问器属性
访问器属性不包含数据值。属性由[[Configurable]] 和 [[Enumerable]] 组成。[[Get]] 和 [[Set]] 属性不是必须的。
[[Get]] 和 [[Set]] 属性类似于PHP中的魔术方法。
var book = { _year:2004, edition:1 }; Object.defineProperty(book, "year", {//因为设置了get、set特性,因此"year"属性为访问器属性。不能再有value,writable特性 get:function(){ return this._year; }, set:function(newValue){ if(newValue > 2004){ this._year = newValue; this.edition += newValue -2004; } } }); book.year = 2005; alert(book.edition); //2
只指定getter意味着属性是不能写。只指定setter意味着属性不可读。
不支持Object.defineProperty()方法的浏览器,使用非标准方法:
obj.__defineGetter__ 和 obj.__defineSetter__
不支持Object.defineProperty()的浏览器不能修改[[Configurable]],[[Enumerable]] 这两个特性
二 定义多个属性
Object.defineProperties() 定义多个属性
var book; Object.defineProperties(book,{ _year : { value : 2004 }, //数据属性 edition : { value : 1 }, //数据属性 year : { //访问器属性 get : function(){ return this._year; }, set: function(){ .... } } });
三 读取属性的特性
Object.getOwnPropertyDescriptor(obj,attributeName)
obj -- 属性所在的对象 、attributeName -- 要读取其描述符的属性名称。返回一个对象,根据属性的类型(数据属性、访问器属性),返回不同的4个特性的值。