1、prototype与__proto__javascript
一、prototype(显式原型):每个函数在建立以后都会拥有一个名为prototype的属性,这个属性指向函数的原型对象。它只存在于函数里,例以下面的例子中:java
function Person(name) { this.name = name; this.showMe = function() { alert(this.name); } }; Person.prototype.from = function() { alert('I come from prototype.'); } var p = new Person('js'); p.from();
Person拥有prototype对象,咱们向对象中添加了一个from方法,构造函数中有一个prototype的属性,改属性是一个指针,指向对应的prototype对象(注意区分一个是属性一个是对象),这里还有一个重要的属性,就是prototype对象中有一个属性constructor,该属性指向对应的构造函数,是一种对应的关系。函数
p是Person构造函数新建的一个实例,new这个方法分为3个部分,最重要的一步是第2步,就本例子来讲 this
<1> var p={}; 也就是说,初始化一个对象p。spa
<2> p.__proto__=Person.prototype;prototype
<3> Person.call(p);也就是说构造p,也能够称之为初始化p。3d
p这个对象没有prototype属性,可是有__proto__属性,这个在下面会提到。指针
2、__proto__code
隐式原型,每个对象都拥有该属性,上面提到新建的实例p,在实例化的时候,能够得出p.__proto__=Person.prototype。那么当咱们调用p.Say()时,首先p中没有Say这个属性, 因而,他就须要到他的__proto__中去找,也就是Person.prototype,而咱们在上面定义了 Person.prototype.Say=function(){}; 因而,就找到了这个方法。对象
具体的例子以下图:
function Person(name) { this.name = name; this.showMe = function() { alert(this.name); } }; Person.prototype.from = function() { alert('I come from prototype.'); } function SubPer() {} SubPer.prototype = new Person('js'); var son = new SubPer(); son.showMe(); //js son.from(); //I come from prototype. alert(son.constructor);
代码里Person具备原型方法,SubPer经过SubPer.prototype = new Person('js')这句代码实现了继承,new的新实例son能够获取Person的方法。
function Person(name) { this.name = name; this.showMe = function() { alert(this.name); } }; Person.prototype = { //重写原型 alertNum:function(){ alert(1111); } } function SubPer() {} SubPer.prototype = new Person('js'); var son = new SubPer();
咱们运行代码,查看son.constructor的值,发现结果以下:
这两个对象的constructor的值都指向了Function,由于咱们在这里重写了一个原型对象,每当新建立一个对象时,就会同时建立它的prototype对象,注意这里的对象是由__proto__指向的,这个对象也得到了constructor属性,对象字面量建立的对象其constructor指向Object,因此由Person new的实例,其constructor也指向了Object
代码作以下的修改:
function Person(name) { this.name = name; this.showMe = function() { alert(this.name); } }; Person.prototype = { alertNum:function(){ alert(1111); } } function SubPer() {} SubPer.prototype = new Person('js'); SubPer.prototype.constructor = SubPer; //修改constructor var son = new SubPer();
constructor的值被修改成Suber构造函数,constructor的值能够被修改覆盖。