一、原型属性
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继承了oObject.prototype的属性,形成了一个原型链,所以Object.prototypep的原型(可以理解为最上游的原型)。
2、o.constructor.prototype,(o为要检测的对象):
new+构造函数创建的对象继承了一个叫constructor的属性,该属性指代该构造函数,o.constructor.prototypeo的原型。使用直接量创建的对象,也有一个叫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不可配置,不可写。自有属性有yzyz的属性描述符如例子中所示,是可写的,不可配置,不可枚举,Object.seal()传入了创建的对象,使得对象:不可扩展,对象里面的属性:不可配置,但没有影响可写性和可枚举性。


君莫言
21 声望9 粉丝

做人如果没梦想,跟咸鱼有什么分别?