在默认的情况下,全部的原型对象都会自己主动获得一个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