0×00背景
我们知道面向对象的语言有一个标志就是有类的概念,通过类可以创建多个具有相同属性和方法的对象。但是ECMAScript中没有类的概念,所以它的对象和其他基于类的语言中的对象有点不同,它是基于原型的面向对象。ECMA-262把对象定义为“无序属性的集合,其属性可以包含基本值,对象或者函数”。每个对象都是基于一个引用类型创建的,这个引用类型可以是原生的引用类型,也可以是自定义的类型。
我们先用最简单的方式创建一个对象
代码如下 | 复制代码 |
var person = new Object(); person.name = “gothic”; person.age = 21; person.job = “f2e”; person.sayName = function(){ alert(this.name); }; |
这个对象里我们添加了三个属性(name,age,job)和一个方法(sayName())。当然我们也可以用对象字面量来重写这个对象:
代码如下 | 复制代码 |
var person = { name:”gothic”, age:21, job:”f2e”, sayName:function(){ alert(this.name); } }
|
0×01属相类型
ECMAScript有两种属性:数据属性和访问器属性
1.数据属性
数据属性包含一个数据值的位置,在这个位置可以读取和写入值。它有四个特性:
Configurable:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,默认值是true.
Enumerable:表示能否通过for-in循环返回属性。像上面第一个例子那样直接在对象上定义属性,默认值为true.
Writable:表示能否修改属性的值。默认值为true.
Value:包含这个属性的数据值,读取属性的时候,从这个位置读,写入属性的时候,把新值保存在这个位置。默认值为:undefined.
如果要修改属性默认的特性,必须要使用Object.defineProperty()方法。这个方法接受三个参数:属性所在的对象、属性的名字、一个描述符对象。其中描述符对象的属性必须是configurable,enumerable,writable,value.通过设置其中的一个或多个值,可以修改对应的特性值,如下:
代码如下 | 复制代码 |
var person={}; Object.defineProperty(person,”name”,{ writable:false, value:”gothic” }); www.111cn.net alert(person.name);//”gothic” person.name=”dyy”; alert(person.name);//”gothic” |
这里我们也可以把writable:false,换为configurable:false,表示不能从对象里删除属性,也就是说如果这是对这个属性调用delete则在非严格模式下不会发生什么,但是在严格模式下会发发生错误。
而且这是如果再想用Object.defineProperty()方法修改除上面那个writable之外的属性则会发生错误,因为Object.defineProperty()可以多出被调用修改同一个属性,但是在把configruable设置为false之后就会有限制了。
一般情况下在调用Object.defineProperty()时,如果不指定,几个特性的默认值都为false。
0×02访问器属性
访问器属性有以下四个特性:
Configurable:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,默认值是true.
Enumerable:表示能否通过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 >2004){ this._year = newValue; this.edition += newValue – 2004; } } }); book.year = 2005; alert(book.edition); //2 |
上面代码访问器属性year包含一个getter函数和setter函数,这里这个_year前面那个下划线是一种常用的记号,用于表示只能通过对象方法访问的是属性,getter函数返回_year的值,setter函数通过计算来确定正确的版本。当然有的时候我们不一定非要同时指定getter和setter,只指定getter表示属性不能写,而指给定setter表示属性不能读,否则在非严格模式下会返回undefined,在严格模式下会出错。
2定义多个属性
利用Object.defineProperties()方法来一次定义多个属性。这个方法接受两个对象参数:一个对象是要添加和修改其属性的对象;第二个对象的属性与第一个对象中要添加或修改的属性一一对应。如下:
代码如下 | 复制代码 |
var book = {}; Object,defineProperties(book,{_year:{ value:2004 }, edition:{value:1}, year:{ get:function(){ return this._year; }, www.111cn.Net set:function(newValue){ if (newValue>2004){ this._year = newValue; this.edition+=newVAlue-2004; } } } }); |
3读取属性的特性
使用Object.getOwnPropertyDescriptor()方法可以取得给定属性的描述符。这个方法接受两个参数:属性所在的对象和要读取其描述符的属性名称。如果获取的是访问器属性,这个对象的值有:configurable,enumerable,get和set,如果是数据属性,这个对象的属性有:configurable,enumerable,writable,value。