**js中的继承,是面向对象的知识,由于js没有类的概念,因此继承是经过对象实现的,谈到继承,就必须说到prototype,就不得不先说下new的过程。
一个小小的列子:**javascript
<script type="text/javascript"> var Person = function () { }; var p = new Person(); </script>
<1> var p={}; 也就是说,初始化一个对象p。java
<2> p.proto=Person.prototype;面试
<3> Person.call(p);也就是说构造p,也能够称之为初始化p。this
关键在于第二步,咱们来证实一下:spa
alert(p.__proto__ === Person.prototype);
这段代码会返回true。说明咱们步骤2的正确。prototype
那么proto是什么?咱们在这里简单地说下。每一个对象都会在其内部初始化一个属性,就是proto,当咱们访问一个对象的属性 时,若是这个对象内部不存在这个属性,那么他就会去proto里找这个属性,这个proto又会有本身的proto,因而就这样 一直找下去,也就是咱们平时所说的原型链的概念。code
按照标准,proto是不对外公开的,也就是说是个私有属性,可是Firefox的引擎将他暴露了出来成为了一个共有的属性,咱们能够对外访问和设置。对象
<script type="text/javascript"> var Person = function () { }; Person.prototype.Say = function () { alert("Person say"); } var p = new Person(); p.Say(); </script>
这段代码很简单,相信每一个人都这样写过,那就让咱们看下为何p能够访问Person的Say。blog
首先var p=new Person();能够得出p.proto=Person.prototype。那么当咱们调用p.Say()时,首先p中没有Say这个属性, 因而,他就须要到他的proto中去找,也就是Person.prototype,而咱们在上面定义了 Person.prototype.Say=function(){}; 因而,就找到了这个方法。继承
下面咱们再看一下有点饶人的列子。
function tiger(){ this.bark=function(){ alert("我会咬人"); }; }; //这里先定义一个老虎方法 function cat(){ this.climb=function(){ alert("我会爬树"); }; }; //定义一个猫方法 //怎么经过继承让老虎也学会爬树?下面开始继承。 tiger.prototype=new cat(); var hnhu=new tiger(); hnhu.climb(); hnhu.valueof(); //是否是很神奇,老虎也会爬树啦,嘿嘿
结合上面的概念,我分析一下具体的继承过程,首先new一个tiger对象,有hnhu.proto=tiger.prototype,有由于tiger.prototype=new cat();
因此tiger.prototype.proto=cat.prototype。至此继承已经付出水面,转化一下获得:
hnhu.proto=tiger.prototype
hnhu.proto.proto=cat.prototype
好,算清楚了以后咱们来看上面的结果,hnhu.climb()。因为hnhu没有climb这个属性,因而去hnhu.proto,也就是 tiger.prototype中去找,因为tiger.prototype中也没有climb,那就去hnhu.proto.proto,也就是cat.prototype中去找,因而就找到了alert(“我会爬树”);的方法。
寻找valueof()也都是一样的道理。这条链就造成了原型链,继承也就经过原型链得以实现。
以上代码图示:
原型和原型链就是这样,跟做用域和做用域链相似,须要慢慢品味其中的精华。
掌握了在来实际用一下把,企鹅的一道继承面试题,大概意思是一只狗刚开始会呜呜的叫,而后发生某种变异,叫声变为变异。要求用原型继承实现上述过程
function dog(){ this.fark=function(){ alert("呜呜"); }; }; function peter(){ this.money=function(){ alert("我是有钱狗"); }; }; peter.prototype=new dog(); peter.prototype.bark=function(){ alert("变异"); }; var tz=new peter(); tz.bark(); tz.fark();
你甚至能够在Object.prototype上增长一些新属性,添加上以后无论是否是变异狗都具备这项属性,由于Object处于原型链的倒数第二层,上面的方法都会继承它的属性,可是这样有必定的问题,全部的狗都具备这个原型链中的方法了。