原型
每个函数都有一个prototype属性,它是一个对象,也称作原型对象,可以将方法和属性写在它上面,而通过这个函数创建出来的实例对象,都能共享这个原型对象下的方法和属性。只需要将想要共享的东西放在该函数的prototype下,不想共享的东西通过构造函数创建
function CretePerson(name){
this.name=name;
}
CreatePerson.prototype.showName=function(){
alert(this.name);
}
var p1=new CretaePerson('hah');
p1.showName();
var p2=new CretaePerson('hehe');
p2.showName();
alert(p1.showName==p2.showName);//true,可见showName()方法共享,共用一个内存,当更改了p1的showName也会影响p2的showName
proto属性
每个实例化对象都有proto属性,它是一个指针,指向函数的prototype,也就是保存了它的地址(JS中任何对象的值都是保存在堆内存中,我们声明的变量只是一个指针,保存了这个对象的实际地址,所以有了地址就能找到对象)
proto属性保存了构造函数的原型对象的地址,通过这个属性就可以拥有原型对象下的所有属性和方法,proto属性实际就是实例化对象和原型对象之间的连接
原型链
每个函数都可以成为构造函数,每个函数都有原型对象,每个原型对象也可以是一个实例化对象
例如:创建了一个函数fun,它是构造函数function的实例化对象,而function的原型对象,又是Object的实例对象。所以fun有个proto属性可以访问到function的原型对象,function原型对象也是个实例对象,也有个proto属性,可以访问到Object的原型对象,所以通过proto属性就形成了一条原型链。
每个实例化对象都可以访问到链子上方的方法和属性,所以fun是可以访问Object原型对象下的方法和属性的,实际上所有对象都可以访问Object的原型对象。
访问规则:先在自身的下面寻找,再去一级一级的往原型链上找
function Aaa(){}
Aaa.prototype.num=;
var a1=new Aaa();
a1.num=;
alert(a1.num);//10
原型对象
原型对象下三种属性:
1、原型对象所带方法和属性
2、constructor构造函数属性 :每个函数的原型对象都有的默认属性,指向函数。每个实例化对象本身是没有constructor属性的,他们下面默认只有一个proto属性,用来连接原型对象,而和构造函数本身是没有直接联系的,所以它的constructor是访问在原型对象上的,当原型对象的constructor变化了,实例化的constructor也会改变。如果这个对象本身既是原型对象又是实例化对象,就拥有constructor属性,无需从原型对象上访问
3、proto属性
function CreatePerson(name){
this.name=name;
}
CreatePerson.prototype.showName=function(){
console.log(this.name);
};
var p1=new CreatePerson('haha');
p1.showName();
console.log(p1.constructor);//来自CreatePerson.prototype
console.log(CreatePerson.prototype);//{showName:{},constructor:CreatePerson,_proto_:Object.prototype}
//可见原型对象保存了:、自身添加的方法,、构造函数constructor,、_proto_(和上一层构造函数原型对象的连接)
console.log(CreatePerson.prototype.__proto__===Object.prototype);//true 这个原型对象本身又是Object的实例化对象,所有_proto_指向Object的原型对象
console.log(CreatePerson.prototype.__proto__===Object);// false 可见是和构造函数下原型对象的连接,不是构造函数
console.log(CreatePerson.prototype.constructor);//CreatePerson CreatePerson.prototype是Object实例化对象,也是原型对象,所以自身拥有constructor属性
console.log(Object.prototype.__proto__); // null 原型链的终点是null
console.log(CreatePerson.__proto__); //function.prototype CreatePerson本身既是构造函数又是function的实例化对象,拥有_proto_属性,指向function的原型对象
console.log(CreatePerson.constructor); // function 继承自function.prototype
console.log(CreatePerson.prototype instanceof CreatePerson)//验证是否在一条原型链上 false
原文:http://www.jianshu.com/p/845ad9b78201