在默认的情况下,全部的原型对象都会自己主动获得一个constructor(构造函数)属性,这个属性包括一个指向prototype属性所在函数的指针。
例如以下图
function Person(){ }
当中上图中Person.prototype .constructor指向Person.而通过这个构造函数,我们能够继续为原型对象加入其它的属性和方法。
例如以下图:
上图的js代码就是
Person.prototype={ name:"Nicholas", age:23, sayName:function(){ return this.name; } };
ECMA-262第5版中管这个指针叫[[Prototype]],尽管在脚本中没有标准方式訪问,我们能够借由Chrome在每一个对象上都支持一个属性_proto_(私有属性不可见),这个链接的存在于实例与构造函数的原型对象之间,而不是存在于实例与构造函数之间。
var p1=new Person();
当创建一个新的p2之后依旧会有一个_proto_属性指向Person的原型(Persion.prototype)。换句话说每一个实例与构造函数没有直接的关系。尽管这实例都不包括属性和方法,但我们却能够调用p1.name查找对象属性的个过程来实现。
此时假设通过p2.name设置属性值后会在对象自己的内存空间中存储name的值,当调用sayName()方法的时候在寻找name时,在自己空间中找到之后就不会去原型对象中查找(注意:原型中的值是不会被替换,不过在查找的时候被覆盖)
var p1=new Person(); alert(p1.name);//Nicholas var p2=new Person();
从本质上讲,假设[[Prototype]]指向调用isPrototypeOf()方法的对象(Person.prototype)。
ECMAScript5中添加一个新的方法.叫做Object.getPrototypeOf(),这种方法返回[[Prototype]]的值
== 能够检測某个对象的constructor
检測某个属性是否是自己是自己的属性用(不是对象原型中的实现)hasOwnProperty(),能够清楚的知道什么时候訪问的自己的属性。什么时候訪问的是原型属性了。
delete能够用来删除实例属性(自己的属性)
in操作:有两种方式操作in操作符。
单独的使用for-in循环中使用。单独是用时,in
会通过对象可以訪问给的属性的返回值。不管属性存在于实例中还是原型中。
//检查某个对象是否是某个函数的原型 alert(Person.prototype.isPrototypeOf(p1));//true ECMAScript5中添加一个新的方法.叫做Object.getPrototypeOf(),在全部支持的实现中,这种方法返回[[Prototype]]的值 alert(Object.getPrototypeOf(p1)==Person.prototype); alert(Object.getPrototypeOf(p1).name); //alert(p1.constructor==Person); //alert(p2.hasOwnProperty("name")) delete p2.name; //alert("name" in p1)//来自原型 p1.id=12; // alert("id" in p1);//来自实例 alert(hasPrototypeProperty(p1,"name")) /** 检查某个属性是否在原型中存在 */ function hasPrototypeProperty(obj,prop){ return ((!obj.hasOwnProperty(prop))&&(prop in obj)); }
var p2=new Person(); Person.prototype.sayHi=function(){ alert(this.name); } p2.sayHi();//能够获取值
而不是构造函数。
function Person(){ } var p1=new Person(); //全部的"范围对象"都继承自这个对象 重写原型对象 Person.prototype.sayHi=function(){ alert(this.name); } //全部的"范围对象"都继承自这个对象 重写原型对象 Person.prototype={ constructor:Person,//显示的设置构造函数的反向引用 name:"Nicholas", age:23, sayName:function(){ return this.name; } }; p1.sayHi();//undefined alert(p1.sayName());//报错 var p2=new Person(); alert(p2.sayName());//Nichola
原型存在的问题
原型对象中的属性是被非常多实例共享的,这个共享对于函数是非常合适的。对于原型中基本值得属性是没有问题的可是,假设属性值包括引用类型值就会有一定的问题了。
function Person(){ } Person.prototype={ constructor:Person,//显示的设置构造函数的反向引用 name:"Nicholas", age:23, friends:["Shelby","Cunrt"], sayName:function(){ return this.name; } }; var p1=new Person(); var p2=new Person(); p1.friends.push("Jack"); alert(p1.friends);//"Shelby","Cunrt","Jack" alert(p2.friends);//"Shelby","Cunrt","Jack" alert(p1.friends==p2.friends);//true
function Person(name,age,friends){ this.name=name; this.age=age; this.friends=friends; } Person.prototype={ constructor:Person,//显示的设置构造函数的反向引用 sayName:function(){ return this.name; } }; var p1=new Person("Tom",20,"Shelby"); var p2=new Person("Alisa",20,["Cunrt","Jack"]); alert(p1.friends);//"Shelby" alert(p2.friends);//"Cunrt","Jack" alert(p1.friends==p2.friends);//false
原文:http://www.cnblogs.com/lcchuguo/p/5369190.html