Js的繼承

js的繼承

@(js)[繼承, js, 前端]

組合繼承是原性鏈繼承和構造函數繼承的合體,它汲取了二者各自的有點,同時又互相補充了各自的弱點,是一種應用十分廣泛的JavaScript繼承模式。下面分別從原性鏈繼承、構造函數繼承分別開始介紹,最后介紹二者的結合——組合繼承。

一、原型鏈

利用原型讓一個引用類型繼承另一個引用類型的屬性和方法
每個構造函數都有一個原型對象,原型對象都包含一個指向構造函數的指針,而實例都包含一個指向原型對象的內部指針。

實現原性鏈的基本模式:

function SuperType(){  //定義了一個父函數
    this.property =true;  
}  
SuperType.prototype.getSuperValue = function(){    //給父函數的原型鏈上添加一個getSuperValue的函數
    returnthis.property;  
}  

function Subtype(){    //定義一個子函數
    this.subproperty =false;  
}  
SubType.prototype = new SuperType();  //SubType實現了繼承SuperType  
SubType.prototype.getSubValue = function(){    //給子函數添加方法
    return this.subproperty;  
}  
var instance = new SubType();  // 實例instance繼承子函數
alert(instance.getSuperValue());  

最后的結果:intance指向SubType的原型,而SubType的原型又指向SuperType的原型,SuperType繼承了Object,所有函數的默認原型都是Object的實例

問題:會產生引用類型值的問題
比如,創建了一個子類的實例,如果對子類實例的屬性進行了修改,那么創建其他子類的時候都會收到影響,代碼如下:

function SuperType(){  
    this.colors =[“red”, “blue”, “green”];  
}  
function SubType(){  
}  
SubType.prototype = new SuperType();  
var instance1 = new SubType();  
instance1.colors.push(“black”);  
alert(instance1.colors);  //red, blue, green, black  
var instance2 = new SubType();  
alert(instance2.colors);   //red, blue, green, black    

以上結果說明會影響其他實例的屬性值

二、借用構造函數

在子類型構造函數的內部調用超類型構造函數

function SuperType(){    // 定義一個父函數
    this.colors =[“red”, “blue”, “green”];  
}  
function SubType{}(   // 定義一個子函數
   SuperType.call(this);     // 繼承了父函數
}  
var instance1 = new SubType();    // 實例instance1繼承子函數
instance1.colors.push(“black”);  
alert(intance1.colors);     //red,blue,green,black  

var instance2 = new SubType();  // 實例instance2繼承子函數
alert(instance2.colors);   //red,blue,green  

使用該方法可以在子類構造函數中向超類型構造函數傳遞參數,如下:

function SuperType(name){    // 定義父函數
    this.name = name;  
}  
function SubType(){    // 定義子函數
SuperType.call(this,“Nicholas”);        //傳入參數,利用這個參數初始化父類構造函數中的name  
this.age = 29;  
}  

var instance = new SubType();  // 實例instance繼承子函數
alert(instance.name);   //Nicholas  
alert(instance.age);   //29  

問題:不方便復用

三、組合式繼承
使用原型鏈實現對原型屬性和方法的繼承,而通過借用構造函數來實現對實例屬性的繼承
示例代碼:

function SuperType(name){    // 定義父函數
this.name = name:   // 定義子函數
this.colors = [“red”, “blue”,“green”];
}  
SuperType.prototype.sayName = function(){   //定義了一個方法,該方法在繼承的子類中也可以用  
    alert(this.name);  
}  
function SubType(name, age){  
SuperType.call(this, name);    //繼承SuperType的一部分,this指SubType,  
this.age = age;    //自己新定義的屬性age也可以進行賦值  
}  
SubType.prototype = new SuperType();     //利用原型繼承,可以使用父類的方法
  
SubType.prototype.sayAge = function(){   //定義SubType特有的新方法  
    alert(this.age);  
}  
var instance1 = new SubType(“Martin”, 10);  
instance1.colors.push(“black”);  
alert(instance1.colors);  //red,blue,green,black  
instance1.sayName();   //Martin  
instance1.sayAge();  //10  

var instance2 = new SubType(“Greg”, 27);  
alert(instance2.colors);   //red,blue,green  
instance2.sayName();  //Greg  
instance2.sayAge();  //27 

綜合例子:

function Person(name, age) {
    this.name = name;
    this.age = age;
}

Person.prototype.hi = function() {
    console.log('Hi, my name is' + this.name) + ",I'm" + this.age + 'years old now.';
};

Person.prototype.LEGS_NUM = 2;
Person.prototype.ARMS_NUM = 2;
Person.prototype.walk = function() {
    console.log(this.name + "is walking...");
}

function Student(name, age, className) {
    Person.call(this, name, age);
    this.className = className;
}

Student.prototype = Objectcreate(Person.prototype);
Student.prototype.constructor = Student;

Student.prototype.hi = function() {
    console.log('Hi, my name is' + this.name + ", I'm" + this.age + "years old now, and from" + this.className + ".");
}

Student.prototype.learn = function(subject) {
    console.log(this.name + 'is learing' + subject + 'at' + this.className + '.');
}

// test
var bosn = new Student('Bosn', 27, 'Class 3,Grade 2');
bosn.hi();  // Hi, my name is Bosn, I'm 27 years old now and from Class3,Grage 2
bosn.LEGS_NUM; // 2
bosn.walk();  // Bosn is walking
bosn.learn('math');  // Bosn is learning math t Class3, Grade 2.
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 一.原型鏈### 原型鏈的基本思想是利用原型讓一個引用類型繼承另一個引用類型的屬性和方法。每一個構造函數都有一個原...
    Devour_z閱讀 212評論 0 0
  • JS作為面向對象的弱類型語言,繼承也是其非常強大的特性之一。那么如何在JS中實現繼承呢?讓我們拭目以待。 JS繼承...
    依依玖玥閱讀 256評論 0 2
  • 1.原型鏈 2.原型鏈繼承 我的理解就是,屬性方法寫在構造函數(父類)的原型上,通過new一個實例,使實例繼承...
    錢羅羅_閱讀 1,114評論 0 0
  • 博客內容:什么是面向對象為什么要面向對象面向對象編程的特性和原則理解對象屬性創建對象繼承 什么是面向對象 面向對象...
    _Dot912閱讀 1,454評論 3 12
  • 一.Props屬性: 組件創建的時候需要用不同的參數進行定制,這些定制的參數就是props(屬性),可為組件內部屬...
    小白哥有話說閱讀 772評論 0 2