javaScript之繼承的基礎學習,實例講解

前段時間,在面試中不停的會被提到繼承。做一個關於繼承的總結。關於對象之間的5中繼承方式


若現在有對象“A”的構造函數:
function A(){
     this.species = "我是A";
}
還有一個對象“B”的構造函數:
 function B() {
        this.name = "我是B";
 }
如何操作,可以使得B繼承到A中的方法?(很容易我們知道A相當於是父對象,B是子對象)

一、構造函數繼承:使用call/apply方法,即:將父對象的構造函數綁定在子對象中。其實就是在子對象添加call/apply。

function B(){
    //使用call繼承
    A.call(this);
    //使用apply繼承: A.apply(this,arguments);
    this.name = "我是B";
}
var b = new B();
console.log(b.species);    //我是A
console.log(b.name);       //我是B

二、prototype模式:將子對象的prototype屬性指向A,則B的實例中就有瞭A。

 B.prototype = new A();
 B.prototype.constructor = B;
 var b = new B();
 console.log(b.species);       //我是A
 console.log(b.name);          //我是B

首先在代碼的第一行中,使用B.prototype = new A(),將B的prototype屬性指向瞭A的實例。也就是說完全刪除瞭prototype對象原先值,重新加值。 在第二行中B.prototype.constructor = B是因為在原型的概念中,我們都知道任何一個函數都會有一個prototype屬性。而他們的prototype屬性都會有一個constructor屬性,指向其的構造函數。通過讓B的constructor重新指回原構造函數,防止造成繼承紊亂。 如果在編程中替換瞭prototype對象,那麼下一步就需要在新的prototype對象加上constructor屬性,並將這個屬性指回原來的構造函數。

三、直接繼承prototype:改寫A對象,將不變的對象都直接寫入A.prototype,所以可以通過B跳過A,直接繼承A.prototype(改進上一中方法的繼承方式)。

首先改寫A對象:
function A(){
    this.a = "B訪問不到我"
}
A.prototype.aa = "B可以訪問到我";
再將B的prototype指向A的prototype
B.prototype = A.prototype;
B.prototype.constructor = B;
var bb = new B();
console.log(bb.a);          //undefined
console.log(bb.aa);         //B可以訪問到我
使用這種模式的繼承,優點是可以將b不需要繼承到的東西放在構造函數內部使得實例化後的B無法訪問,而節省瞭內存。缺點是因為B.prototype和A.prototype指向瞭同一個對象,所以會造成如果修改瞭B.prototype 都會影響到A.prototype。可以在上面的代碼之後加入一句話判斷是否是這樣子的:
console.log(A.prototype.constructor);      //B

四、利用空對象繼承:改進上一個。不會污染到父對象。

var F = function(){};
F.prototype = A.prototype;
B.prototype = new F();
B.prototype.constructor = B;
新申請的F是空對象,所以幾乎不占內存。這時,修改B的prototype對象,就不會影響到A的prototype對象瞭。

五、拷貝繼承:將父對象的所有屬性和方法都拷貝在子對象上。

上面的都是采用prototype對象,實現繼承。我們也可以換一種思路,純粹采用”拷貝”方法實現繼承。簡單說,如果把父對象的所有屬性和方法,拷貝進子對象,也就可以實現繼承。

和之前的一樣,將不需要B去繼承的還是放在A的內部 將A的屬性都放在A.prototype上 再寫一個可以實現拷貝的目的的函數。這個函數的作用是將父級對象的prototype屬性,拷貝在子對象的prototype上。

function extend(Child,Parent){
    var p = Parent.prototype;
    var c = Child.prototype;
    for (var i in p){
        c[i] = p[i];
    }
    c.uber = p;
}
使用方式:
extend(B,A);
var b = new B();

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *