ES5中的对象是指无序的属性的集合。(属性可以是基本值、对象和函数)。
对象的属性类型有两种,一种是数据属性,是数据值的保存位置;另一种是访问器属性,包含getter和setter函数。
数据属性包含一个数据值的位置,在这个位置可以读取和写入值。数据属性有四个描述其特征的特性。(这些特性是为javascript内部引擎服务的,不能直接访问,所以将它们放在方括号中。)
!!!此处说的默认值是指直接定义时的默认值,与使用defineProperty()定义的属性默认值不同
数据属性可以直接使用对象字面量或new Object对象来定义,而这些特性值不能直接访问,要修改默认的特性,要使用定义在Object对象中的defineProperty()函数。
!!!在调用 Object.defineProperty()方法时,如果不指定configurable、enumerable 和writable 特性的默认值都是 false。
示例如下:
// 使用对象字面量创建一个对象
var person = {
};
//修改该对象属性的默认特性
/*
第一个参数为属性所在的对象。
第二个参数为要定义的属性名。
第三个参数是其特性描述符的对象。(属性为configurable, enumerable, writable, value)
*/
Object.defineProperty(person, "name", {
writable: false,
value: "Nicholas"
});
//这样就可以访问定义好的数据属性了
alert(person.name); //"Nicholas"
//在定义属性时将writable设定为false,所有对name属性的值更改操作无效。(严格模式下会报错)
person.name = "Greg";
alert(person.name); //"Nicholas"
另外将把 configurable 设置为 false,表示不能从对象中删除属性。如果对这个属性调用 delete,则在非严格模式下什么也不会发生,而在严格模式下会导致错误。一旦把属性定义为不可配置的,就不能再把它变回可配置了。 此时,Object.defineProperty()方法修改除 writable 之外的特性,都会导致错误。
访问器属性不包含数据值,包含一对 getter 和 setter 函数(不必需)。
在读取访问器属性时,会调用 getter 函数,这个函数负责返回有效的值;
在写入访问器属性时,会调用setter 函数并传入新值,这个函数负责决定如何处理数据。
访问器属性也包含了四个特性。
访问器属性不能直接定义,必须要使用Obiect.defineProperty()来定义。定义的过程于数据属性类似。
var book = {
_year: 2004, //'_'是一种常用于表示只能通过对象方法访问的属性的记号
edition: 1
};
/*
第一个参数为属性所在的对象。
第二个参数为要定义的访问器属性名。
第三个参数是其特性描述符的对象。(属性为configurable, enumerable, get, set)
*/
Object.defineProperty(book, "year", {
// 访问一个私有变量
get: function(){
return this._year;
},
// set常用于改变一个变量导致其他变量改变的情形
set: function(newValue){
if (newValue > 2004) {
this._year = newValue;
this.edition += newValue - 2004;
}
}
});
book.year = 2005;
alert(book.edition); //2
不一定非要同时指定 getter 和 setter。
只指定 getter 意味着属性是不能写,在非严格模式下尝试写入属性会被忽略。
类似地,只指定 setter 函数的属性也不能读,在非严格模式下会返回 undefined。
在严格模式下,尝试写入只指定了 getter 函数的属性和读取只指定了 setter函数的属性会抛出错误。
上面介绍的Object.defineProperty()方法只能定义单个属性,Object.defineProperties()方法可以通过描述符一次定义多个属性。
!!!在调用 Object.defineProperties()方法时,如果不指定configurable、enumerable 和writable 特性的默认值都是 false。
示例如下:
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;
}
}
}
});
JS中的Object。getOwnPropertyDescriptor()方法可以取得给定的对象属性描述符。对上一节中定义的book对象,有以下示例:
// 该方法接受两个参数 第一个参数是对象 第二个参数是对应的属性
var descriptor = Object.getOwnPropertyDescriptor(book, "_year");
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.enumerable); //false
alert(typeof descriptor.get); //"function"
在 JavaScript 中,可以针对任何对象——包括 DOM 和 BOM 对象,使用 Object.getOwnPropertyDescriptor()方法。