js中繼承能夠分爲兩種:對象冒充和原型鏈方式javascript
1、對象冒充包括三種:臨時屬性方式、call()及apply()方式html
1.臨時屬性方式: java
1 function A(x){ 2 this.x=x; this.say = function(){ alert('My name is '+this.name); } 3 } 4 function B(x,y){ 5 this.tmpObj=A; 6 this.tmpObj(x); 7 delete this.tmpObj; 8 this.id = y; this.showId = function(){ alert('Good morning,Sir,My work number is '+this.id); } 9 } var simon = new B('Simon',9527); simon.say(); simon.showId();
/**/第五、六、7行:建立臨時屬性tmpObj引用構造函數A,而後在B內部執行,執行完後刪除。當在B內部執行了 this.x=x後(這裏的this是B的對象),B固然就擁有了x屬性,固然B的x屬性和A的x屬性二者是獨立,因此並不能算嚴格的繼承。第五、六、7行有更簡單的實現,就是經過call(apply)方法:A.call(this,x);segmentfault
2.call()/apply()方式:實質上是改變了this指針的指向、app
function Person(name){ this.name = name; this.say = function(){ alert('My name is '+this.name); } } function F2E(name,id){ Person.call(this,name); //apply()方式改爲Person.apply(this,[name]); this.id = id; this.showId = function(){ alert('Good morning,Sir,My work number is '+this.id); } } var simon = new F2E('Simon',9527); simon.say(); simon.showId();
/**/call和apply均可以實現繼承,惟一的一點參數不一樣,func.call(func1,var1,var2,var3)對應的apply寫法爲:func.apply(func1,[var1,var2,var3])。函數
經過對象冒充的方式,沒法繼承經過prototype方式定義的變量和方法:this
function Person(name){ this.name = name; this.say = function(){ alert('My name is '+this.name); } } Person.prototype.age = 20; Person.prototype.sayAge = function(){alert('My age is '+this.age)}; function F2E(name,id){ Person.apply(this,new Array(name)); this.id = id; this.showId = function(){ alert('Good morning,Sir,My work number is '+this.id); } } var simon = new F2E('Simon',9527); simon.sayAge(); //提示TypeError: simon.sayAge is not a function
2、原型鏈繼承(能夠繼承經過prototype方式定義的變量和方法:)spa
一:.net
function Parent(){ this.name = 'mike'; } function Child(){ this.age = 12; } Child.prototype = new Parent();//Child繼承Parent,經過原型,造成鏈條 var test = new Child(); alert(test.age); alert(test.name);//獲得被繼承的屬性 //繼續原型鏈繼承 function Brother(){ //brother構造 this.weight = 60; } Brother.prototype = new Child();//繼續原型鏈繼承 var brother = new Brother(); alert(brother.name);//繼承了Parent和Child,彈出mike alert(brother.age);//彈出12
二:prototype
function Person(){ this.name = 'Simon'; } Person.prototype.say = function(){ alert('My name is '+this.name); } function F2E(id){ this.id = id; this.showId = function(){ alert('Good morning,Sir,My work number is '+this.id); } } F2E.prototype = new Person(); var simon = new F2E(9527); simon.say(); simon.showId(); alert(simon.hasOwnProperty('id')); //檢查是否爲自身屬性
原型鏈能夠理解成:js中每一個對象均有一個隱藏的__proto__屬性,一個實例化對象的__proto__屬性指向其類的prototype方法,而這個prototype方法又能夠被賦值成另外一個實例化對象,這個對象的__proto__又須要指向其類,由此造成一條鏈,也就是前面代碼中的 F2E.prototype = new Person();
缺點顯而易見,原型鏈方式繼承,就是實例化子類時不能將參數傳給父類,也就是爲何實例二中的function Person()沒有參數,而是直接寫成了this.name=」Simon」的緣由。下面的代碼將不能達到預期的效果:
unction Person(name){ this.name = name; } Person.prototype.say = function(){ alert('My name is '+this.name); } function F2E(name,id){ this.id = id; this.showId = function(){ alert('Good morning,Sir,My work number is '+this.id); } } F2E.prototype = new Person(); //此處沒法進行傳值,this.name或者name都不行,直接寫F2E.prototype = new Person('wood')是能夠的,可是這樣的話simon.say()就變成了My name is wood var simon = new F2E("Simon",9527); simon.say(); //彈出 My name is undefined simon.showId();
綜上分析所得:javascript中最經常使用的繼承模式 組合繼承
<script type="text/javascript"> //建立基類 function Person(name, age) { this.name = name; this.age = age; } //經過原型方式給基類添加函數(這樣能夠服用此函數) Person.prototype.showName = function () { alert(this.name); } //建立子類 function Student(name, age, score) { this.score = score; Person.call(this,name,age); } //把父類的實例賦值給子類的原型 Student.prototype = new Person(); //經過原型方式給子類添加函數(這樣能夠服用此函數) Student.prototype.showScore = function () { alert(this.score); } //如下爲使用 var student = new Student("zhangsan", 22, 100); student.showName(); student.showScore(); </script>
參照:http://www.jb51.net/article/24556.htm
http://www.jb51.net/article/47619.htm
http://www.javashuo.com/article/p-ueosnihj-ew.html
http://www.cnblogs.com/ljchow/archive/2010/06/08/1753526.html