一、原型属性
1、对象的原型属性是用来继承属性的,这个属性如此重要,我们通常称为:对象的原型属性或对象的原型。
对象的原型是在对象实例化的时候就设置好的:
(1)、通过对象直接量创建的对象的原型是Object.prototype
(2)、通过(new
+构造函数)的方式创建的对象的原型是(构造函数的prototype
属性) 如:var arr=new Array()
,arr
的原型是:Array.prototype
(3)、通过new create()
,创建的对象的原型是该方法的第一个参数,如: var obj=new create(o);obj
的原型是o
2、检测对象的原型方法:
1、o.isPrototypeOf(p)
,(o
为原型,p
为要检测的对象):
var o={x:0,y:1};
var p=new create(o);
o.isPrototypeOf(p); //true
Object.prototype.isPrototypeOf(p); //true
上面例子中通过new create()
创建对象,o
作为p
的原型,o
为字面两创建的对象,o
的原型是Object.prototype
,p
继承了o
的属性,o
继承了Object.prototype
的属性,所以p
继承了o
和Object.prototype
的属性,形成了一个原型链,所以Object.prototype
是p
的原型(可以理解为最上游的原型)。
2、o.constructor.prototype
,(o
为要检测的对象):new
+构造函数创建的对象继承了一个叫constructor
的属性,该属性指代该构造函数,o.constructor.prototype
即o
的原型。使用直接量创建的对象,也有一个叫constructor
的属性,该属性指代Object
构造函数,所以直接量创建的对象的真正原型是:o.constructor.prototype
,使用o.constructor.prototype
方法来检测对象的原型并不可靠,在以后的文章中会提到。
3、在ECMAScript5中,Object.getPrototypeOf(o)
这个方法来获取对象的原型,这个方法IE8及以下不支持。
二、类属性
对象的类属性(class
)是一个字符串,ECMAScript3和ECMAScript5没有提供设置对象类的方法,有一种间接的方法访问对象类的属性:toString()
,该方法继承自Object.prototype
返回字符串"[Object class]"
,我们只要取返回字符串的下标为8
到-1
的字符串就获取了对象的类属性class
了,但是有很多的自定义对象重写了toString()
方法,获取对象的类属性时须调用Function.call()
方法,下面是返回任意对象的类属性的classOf()
函数:
function classOf(o){
if(o===null) return "Null";
if(o===undefined) return "Undefined";
return Object.prototype.toString().call(o).slice(8,-1);
}
classOf(1); //"Number"
classOf(""); //"String"
classOf(new Array()); //"Array"
classOf(new Date()); //"Date"
classOf(new RegExp()); //"RegExp"
classOf(true); //"Boolean"
classOf({}); //"Object"
classOf(window); //"window"(客户端的宿主对象)
function F(){} //自定义一个构造函数
classOf(new F()); //"Object",对于自定义的对象无法区分类
三、可扩展性
对象的可扩展性表示对象是否可以添加新的属性,内置对象和自定义对象默认都是可扩展的,可以通过方法设置为不可扩展的,宿主对象的可扩展性是由javascript的引擎定义的。
1、查询对象的可扩展性,Object.isExtensible()
,参数传入要查询的对象,如:
var obj={};
Object.isExtensible(obj); //该方法IE8及以下不支持
2、设置对象的可扩展性,
(1)、Object.preventExtensions()
,参数传入要设置的对象,一旦对象的可扩展性设置为不可扩展的,就无法复原为可扩展的了,但不影响对象的继承属性,通过在对象的原型中添加属性,这个不可扩展的对象任然会继承原型新添加的属性。使用该方法后,对象:不可扩展、可配置、可写。(可枚举不受影响,存取器属性不受影响)
(2)、Object.seal()
,参数传入要设置的对象,该方法可设置对象为不可扩展的和对象的属性是不可配置的,也就是说对象不能添加新的属性,不能配置和删除该对象属性,但是该对象的可写的属性任然可以设置。使用该方法后,对象:不可扩展、不可配置、可写。(可枚举不受影响,存取器属性不受影响)
(3)、Object.freeze()
,参数传入要设置的对象,"冻结"对象,使用该方法后,对象:不可扩展、不可配置、不可写。(可枚举不受影响,存取器属性不受影响)
var obj=Object.seal(Object.create(Object.freeze({x:1}),{
y:{value:2,writable:true},
z:{value:3,writable:true}
}));
obj.x=-1;
obj.y=-2
obj.x; //1,Object.freeze({x:1});设置该对象不可扩展、不可配置、不可写
obj.y;//-2,Object.seal(),设置该对象为不可扩展、不可配置、没有设置对象的可写性
上面例子中Object.create()
创建了一个对象原型是Object.freeze({x:1});
原型是不可扩展的,继承属性x不可配置,不可写。自有属性有y
和z
,y
、z
的属性描述符如例子中所示,是可写的,不可配置,不可枚举,Object.seal()
传入了创建的对象,使得对象:不可扩展,对象里面的属性:不可配置,但没有影响可写性和可枚举性。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。