十:ECMAScript 5 增强的对象模型
最后更新于:2022-04-01 20:32:12
## 一、属性和描述符
1、概述:在ECMAScript 5中,属性模型已经完全被重写了,并规定了value,writable,configurable,enumerable,get和set共6个属性,用于完成不同的功能。例如:
~~~
{
value:"属性值",
writable:true, //定义属性是否可以改变,默认为TRUE
configurable:true, //定义属性是否可以被删除,默认为TRUE
enumerable:true //定义属性是否可以迭代,默认为TRUE
}
~~~
2、注意事项
要使用ECMAScript 5 增强的对象模型定义属性,不能再使用原来的模式。
~~~
function Person(){}
Person.prototype.nickName=
{
value:"Tom",
writable:true,
enumerable:true,
configurable:true
};
var per = new Person;
alert(JSON.stringify(per.nickName));
~~~
Google运行结果:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-30_57c54ec5be419.jpg)
上述的定义并没有应用ECMAScript 5的增强对象模型,属性nickName的值其实是一个对象,而我们想要的仅仅是Tom。
## 二 、使用ECMAScript 5 增强的对象模型定义属性
1、定义属性:Object.defineProperty(obj,prop,desc)
1.1 参数详解:
obj是一个对象,若要为一个类的所有实例定义属性,则将该参数指定为该类的原型对象;prop是一个字符串,指定属性名;desc是一个对象,包含属性的描述。
1.2 重新定义Person
~~~
function Person(){}
Object.defineProperty(Person.prototype,"nickName",
{
value:"Tom",
writable:true,
enumerable:true,
configurable:true
});
var per = new Person;
alert(JSON.stringify(per.nickName));
~~~
Google运行结果:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-30_57c54ec5d4381.jpg)
2、定义get和set存取器方法
Object。defineProperty()也可以用于定义get和set方法,由于get和set方法需要一个中间的私有变量,所以,需要定义一个自执行的匿名函数包含Object.defineProperty()方法的定义。
~~~
function Person(){}
(function()
{
var nick = "Tom";
Object.defineProperty(Person.prototype,"nickName",
{
get:function(){return nick;},
set:function(value){nick = value;}
});
})();
var per1 = new Person;
document.write(per1.nickName+"
"); per1.nickName = "John"; document.write(per1.nickName); ~~~ Google运行结果 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-30_57c54ec5e8bb2.jpg) 3、一次定义多个属性 Object.defineProperties()可以一次定义或修改多个属性,为Person类定义nickName和age属性 ~~~ function Person(){} Object.defineProperties(Person.prototype, { "nickName": { value:"Tom", writable:true }, "age": { value:20, configurable:false, writable:false } }); ~~~ ## 三 、使用ECMAScript 5 增强的对象模型获取属性 1、Object.getOwnPropertyDescriptor(obj,prop)方法可以获取一个属性的描述信息。 1.1 参数详解 obj是一个对象,指定要获取属性的对象;prop是一个字符串,用于指定要获取的属性名。 ~~~ function Person(){} var per = new Person; Object.defineProperties(per, { "nickName": { value:"Tom", writable:true }, "age": { value:20, configurable:false, writable:false } }); var age = Object.getOwnPropertyDescriptor(per,"age"); alert(JSON.stringify(age)); ~~~ Google运行结果 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-30_57c54ec6070f4.jpg) 2、枚举属性 Object.keys(obj)是一个枚举对象obj所有可以枚举的属性的静态方法,返回值是一组字符串,每个字符串就是属性名。 Object.getOwnPropertyNames(obj)可以实现同样的功能,但是能列出所有能枚举和不能枚举的属性。该方法不能实现向前兼容,因为ECMAscript3没有相关的方法可以获得不能枚举的属性。 ## 四 、密封对象和动态对象 1、概述:默认情况下,JS创建的对象都是动态的,允许在运行为对象添加属性和方法。使用ECMAScript 5增强的对象模型,就可以定义密封对象,它是通过object.preventExtensions(obj)、Object.seal(obj)、Object.freeze(obj)等静态方法实现。 2、Object.preventExtensions(obj):锁定一个对象,密封对象不允许添加新成员。同时提供了Object.isExtensible(obj)方法检查一个对象是否可以增加成员,即是否应用了Object.preventExtensions(obj)方法,没有应用则返回TRUE,否则返回FALSE。obj是要密封的对象,若要密封一个类,该参数可以指定为类的原型对象。 ~~~ function Person(name,age) { this.name = name; this.age = age; } Person.prototype.show = function() { document.write("my name is "+this.name+", and age is "+this.age+"
"); }; var per = new Person("康",20); per.show(); document.write("是否可以添加成员:"+Object.isExtensible(per)+"
"); Object.preventExtensions(per); document.write("是否可以添加成员:"+Object.isExtensible(per)+"
"); per.hobby = "篮球"; //不能再添加属性 document.write(per.hobby+"
"); document.write(delete per.hobby); //但是可以删除属性 ~~~ Google运行结果 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-30_57c54ec619f8f.jpg) 3、Object.seal(obj):锁定一个对象,密封对象不允许添加和删除新成员。同时提供了Object.isSealed(obj)方法检查一个对象是否可以增加成员,即是否应用了Object.preventExtensions(obj)方法,没有应用则返回TRUE,否则返回FALSE。obj是要密封的对象,若要密封一个类,该参数可以指定为类的原型对象。 ~~~ function Person(name,age) { this.name = name; this.age = age; } Person.prototype.show = function() { document.write("my name is "+this.name+", and age is "+this.age+"
"); }; var per = new Person("康",20); per.show(); document.write("是否可以添加成员:"+Object.isSealed(per)+"
"); Object.seal(per); document.write("是否可以添加成员:"+Object.isSealed(per)+"
"); per.hobby = "篮球"; document.write(per.hobby+"
"); document.write(delete per.age); //不能删除,返回false ~~~ Google运行结果 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-30_57c54ec62e6c9.jpg) 4、Object.freeze(obj):锁定一个对象,密封对象不允许添加和删除新成员,所有属性均变为只读。同时提供了Object.isFrozen(obj)方法检查一个对象是否可以增加成员,即是否应用了Object.freeze(obj)方法,没有应用则返回TRUE,否则返回FALSE。obj是要密封的对象,若要密封一个类,该参数可以指定为类的原型对象。 ~~~ function Person(name,age) { this.name = name; this.age = age; } Person.prototype.show = function() { document.write("my name is "+this.name+", and age is "+this.age+"
"); }; var per = new Person("康",20); per.show(); document.write("是否可以添加成员:"+Object.isFrozen(per)+"
"); Object.freeze(per); document.write("是否可以添加成员:"+Object.isFrozen(per)+"
"); per.age = 25; //不能改变,仍为20 document.write(per.age+"
"); document.write(delete per.name); ~~~ Google运行结果 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-30_57c54ec645839.jpg) ## 五 、根据原型对象创建对象 使用Object.create(proto[,props])方法可以为指定的对象和可选的属性创建一个新对象。proto指向一个对象,该对象作为新建对象的原型对象,props指定要增加的属性,可选。该方法的功能相当于将新创建的对象的原型作为参数,同时使用Object.defineProperties(props)方法定义属性。
';
"); per1.nickName = "John"; document.write(per1.nickName); ~~~ Google运行结果 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-30_57c54ec5e8bb2.jpg) 3、一次定义多个属性 Object.defineProperties()可以一次定义或修改多个属性,为Person类定义nickName和age属性 ~~~ function Person(){} Object.defineProperties(Person.prototype, { "nickName": { value:"Tom", writable:true }, "age": { value:20, configurable:false, writable:false } }); ~~~ ## 三 、使用ECMAScript 5 增强的对象模型获取属性 1、Object.getOwnPropertyDescriptor(obj,prop)方法可以获取一个属性的描述信息。 1.1 参数详解 obj是一个对象,指定要获取属性的对象;prop是一个字符串,用于指定要获取的属性名。 ~~~ function Person(){} var per = new Person; Object.defineProperties(per, { "nickName": { value:"Tom", writable:true }, "age": { value:20, configurable:false, writable:false } }); var age = Object.getOwnPropertyDescriptor(per,"age"); alert(JSON.stringify(age)); ~~~ Google运行结果 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-30_57c54ec6070f4.jpg) 2、枚举属性 Object.keys(obj)是一个枚举对象obj所有可以枚举的属性的静态方法,返回值是一组字符串,每个字符串就是属性名。 Object.getOwnPropertyNames(obj)可以实现同样的功能,但是能列出所有能枚举和不能枚举的属性。该方法不能实现向前兼容,因为ECMAscript3没有相关的方法可以获得不能枚举的属性。 ## 四 、密封对象和动态对象 1、概述:默认情况下,JS创建的对象都是动态的,允许在运行为对象添加属性和方法。使用ECMAScript 5增强的对象模型,就可以定义密封对象,它是通过object.preventExtensions(obj)、Object.seal(obj)、Object.freeze(obj)等静态方法实现。 2、Object.preventExtensions(obj):锁定一个对象,密封对象不允许添加新成员。同时提供了Object.isExtensible(obj)方法检查一个对象是否可以增加成员,即是否应用了Object.preventExtensions(obj)方法,没有应用则返回TRUE,否则返回FALSE。obj是要密封的对象,若要密封一个类,该参数可以指定为类的原型对象。 ~~~ function Person(name,age) { this.name = name; this.age = age; } Person.prototype.show = function() { document.write("my name is "+this.name+", and age is "+this.age+"
"); }; var per = new Person("康",20); per.show(); document.write("是否可以添加成员:"+Object.isExtensible(per)+"
"); Object.preventExtensions(per); document.write("是否可以添加成员:"+Object.isExtensible(per)+"
"); per.hobby = "篮球"; //不能再添加属性 document.write(per.hobby+"
"); document.write(delete per.hobby); //但是可以删除属性 ~~~ Google运行结果 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-30_57c54ec619f8f.jpg) 3、Object.seal(obj):锁定一个对象,密封对象不允许添加和删除新成员。同时提供了Object.isSealed(obj)方法检查一个对象是否可以增加成员,即是否应用了Object.preventExtensions(obj)方法,没有应用则返回TRUE,否则返回FALSE。obj是要密封的对象,若要密封一个类,该参数可以指定为类的原型对象。 ~~~ function Person(name,age) { this.name = name; this.age = age; } Person.prototype.show = function() { document.write("my name is "+this.name+", and age is "+this.age+"
"); }; var per = new Person("康",20); per.show(); document.write("是否可以添加成员:"+Object.isSealed(per)+"
"); Object.seal(per); document.write("是否可以添加成员:"+Object.isSealed(per)+"
"); per.hobby = "篮球"; document.write(per.hobby+"
"); document.write(delete per.age); //不能删除,返回false ~~~ Google运行结果 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-30_57c54ec62e6c9.jpg) 4、Object.freeze(obj):锁定一个对象,密封对象不允许添加和删除新成员,所有属性均变为只读。同时提供了Object.isFrozen(obj)方法检查一个对象是否可以增加成员,即是否应用了Object.freeze(obj)方法,没有应用则返回TRUE,否则返回FALSE。obj是要密封的对象,若要密封一个类,该参数可以指定为类的原型对象。 ~~~ function Person(name,age) { this.name = name; this.age = age; } Person.prototype.show = function() { document.write("my name is "+this.name+", and age is "+this.age+"
"); }; var per = new Person("康",20); per.show(); document.write("是否可以添加成员:"+Object.isFrozen(per)+"
"); Object.freeze(per); document.write("是否可以添加成员:"+Object.isFrozen(per)+"
"); per.age = 25; //不能改变,仍为20 document.write(per.age+"
"); document.write(delete per.name); ~~~ Google运行结果 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-30_57c54ec645839.jpg) ## 五 、根据原型对象创建对象 使用Object.create(proto[,props])方法可以为指定的对象和可选的属性创建一个新对象。proto指向一个对象,该对象作为新建对象的原型对象,props指定要增加的属性,可选。该方法的功能相当于将新创建的对象的原型作为参数,同时使用Object.defineProperties(props)方法定义属性。