国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

類的繼承

BothEyes1993 / 2398人閱讀

摘要:一何為繼承繼承,是子類繼承父類的特征和行為,使得子類對象具有父類的實例域和方法。目的是通過繼承該父類,產出計算機子類。將父類的原型傳遞給子類使用操作符對父類進行實例化并將實例對象賦值給子類的。

本文講述JavaScript中類繼承的實現方式,并比較實現方式的差異。
一、何為繼承
繼承,是子類繼承父類的特征和行為,使得子類對象具有父類的實例域和方法。
繼承是面向對象編程中,不可或缺的一部分。
1.1 優點

減少代碼冗余 父類可以為子類提供通用的屬性,而不必因為增加功能,而逐個修改子類的屬性

代碼復用 同上

代碼易于管理和擴展 子類在父類基礎上,可以實現自己的獨特功能

1.2 缺點

耦合度高 如果修改父類代碼,將影響所有繼承于它的子類

影響性能 子類繼承于父類的數據成員,有些是沒有使用價值的。但是,在實例化的時候,已經分配了內存。所以,在一定程度上影響程序性能。

二、例子

例子以圖書館中的書入庫歸類為例。
以下是簡化后的父類Book(也可稱為基類)。
目的是通過繼承該父類,產出Computer(計算機)子類。
并且,子類擁有新方法say,輸出自己的書名。

function Book(){
    this.name = ""; // 書名
    this.page = 0; // 頁數
    this.classify = ""; // 類型
}
Book.prototype = {
    constructor: Book,
    init: function(option){
        this.name = option.name || "";
        this.page = option.page || 0;
        this.classify = option.classify || "";
    },
    getName: function(){
        console.log(this.name);
    },
    getPage: function(){
        console.log(this.page);
    },
    getClassify: function(){
        console.log(this.classify);
    }
};

接下來會講解子類Computer幾種繼承方式的實現和優化方法。開始飆車~

三、實例式繼承
function Computer(){
    Book.apply(this, arguments);
}
Computer.prototype = new Book();
Computer.prototype.constructor = Computer;
Computer.prototype.init = function(option){
    option.classify = "computer";
    Book.prototype.init.call(this, option);
};
Computer.prototype.say = function(){
    console.log("I"m "+ this.name);
}
3.1 調用父類構造器進行初始化
function Computer(){
    Book.apply(this, arguments);
}

Computer的構造函數里,調用父類的構造函數進行初始化操作。使子類擁有父類一樣的初始化屬性。

3.2 將父類的原型傳遞給子類

Computer.prototype = new Book();使用new操作符對父類Book進行實例化,并將實例對象賦值給子類的prototype
這樣,子類Computer就可以通過原型鏈訪問到父類的屬性。

3.3 缺點

父類Book的構造函數被執行了2次

一次是在Computer的構造函數里Book.apply(this, arguments);

一次是在Computer.prototype = new Book();

這種模式,存在一定的性能浪費。

父類實例化無法傳參

Computer.prototype = new Book();,這種實例化方式,無法讓Book父類接收不固定的參數集合。

四、原型式繼承
function Computer(){
    Book.apply(this, arguments);
}
Computer.prototype = Object.create(Book.prototype);
Computer.prototype.constructor = Computer;
Computer.prototype.init = function(option){
    option.classify = "computer";
    Book.prototype.init(option);
};
Computer.prototype.say = function(){
    console.log("I"m "+ this.name);
}

這里的改進:是使用Object.create(Book.prototype)。它的作用是返回一個繼承自原型對象Book.prototype的新對象。且該對象下的屬性已經初始化。
Object.create生成新對象,并不會調用到Book的構造函數。
這種方式,也可以通過原型鏈實現繼承。

五、Object.create的簡單版兼容

由于低版本的瀏覽器是不支持Object.create的。所以這里簡單介紹下兼容版本:

Object.create = function(prototype){
    function F(){}
    F.prototype = prototype;
    return new F();
}

原理是定義一個空的構造函數,然后修改其原型,使之成為一個跳板,可以將原型鏈傳遞到真正的prototype。

六、函數化繼承

上述兩種實現方式,都存在一個問題:不存在私有屬性私有方法。也就是說,存在被篡改的風險。
接下來就用函數化來化解這個問題。

function book(spec, my){
    var that = {};

    // 私有變量
    spec.name = spec.name || ""; // 書名
    spec.page = spec.page || 0; // 頁數
    spec.classify = spec.classify || ""; // 類型

    var getName = function(){
        console.log(spec.name);
    };
    var getPage = function(){
        console.log(spec.page);
    };
    var getClassify = function(){
        console.log(spec.classify);
    };

    that.getName = getName;
    that.getPage = getPage;
    that.getClassify = getClassify;

    return that;
}

function computer(spec, my){
    spec = spec || {};
    spec.classify = "computer";
    var that = book(spec, my);

    var say = function(){
        console.log("I"m "+ spec.name);
    };
    that.say = say;

    return that;
}

var Ninja = computer({name: "JavaScript忍者秘籍", page: 350});

函數化的優勢,就是可以更好地進行封裝和信息隱藏。
也許有人疑惑為什么用以下這種方式聲明和暴露方法:

var say = function(){
    console.log("I"m "+ spec.name);
};
that.say = say;

其實是為了保護對象自身的完整性。即使that.say被外部篡改或破壞掉,function computer內部的say方法仍然能夠正常工作。
另外,解釋下thatspecmy的作用:

that是一個公開數據存儲容器,暴露出去的數據接口,都放到這個容器

spec是用來存儲創建新實例所需的信息,屬于實例之間共同編輯的數據

my是用來存儲父類、子類之間共享的私密數據容器,外部是訪問不到的。

七、ES6繼承

最后,看下現代版ES6的類繼承。不禁感慨以前的刀耕火種,是多么折磨人

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/96422.html

相關文章

  • C++繼承

    摘要:例如,在關鍵字為的派生類當中,所繼承的基類成員的訪問方式變為。繼承中的作用域在繼承體系中的基類和派生類都有獨立的作用域。為了避免類似問題,實際在繼承體系當中最好不要定義同名的成員。 ...

    URLOS 評論0 收藏0
  • 關于繼承的那些事!

    摘要:格式子類名父類名好處提高了代碼的復用性提高了代碼的維護性通過少量的修改,滿足不斷變化的具體要求讓類與類產生了一個關系,是多態的前提要求有共同的屬性或操作有細微的差別繼承的弊端讓類的耦合性增強。 showImg(https://segmentfault.com/img/remote/1460000019321816?w=600&h=242); 第二階段 JAVA面向對象 第二章 繼承 其...

    soasme 評論0 收藏0
  • JavaScript 的繼承方式及優缺點

    摘要:繼承簡介在的中的面向對象編程,繼承是給構造函數之間建立關系非常重要的方式,根據原型鏈的特點,其實繼承就是更改原本默認的原型鏈,形成新的原型鏈的過程。 showImg(https://segmentfault.com/img/remote/1460000018998684); 閱讀原文 前言 JavaScript 原本不是純粹的 OOP 語言,因為在 ES5 規范中沒有類的概念,在 ...

    nanchen2251 評論0 收藏0
  • Javascript 設計模式讀書筆記(三)——繼承

    摘要:的繼承方式屬于原型式繼承,非常靈活。當使用關鍵字執行類的構造函數時,系統首先創建一個新對象,這個對象會繼承自構造函數的原型對象新對象的原型就是構造函數的屬性。也就是說,構造函數用來對生成的新對象進行一些處理,使這個新對象具有某些特定的屬性。 繼承這個東西在Javascript中尤其復雜,我掌握得也不好,找工作面試的時候在這個問題上栽過跟頭。Javascript的繼承方式屬于原型式繼承,...

    cangck_X 評論0 收藏0
  • C++基礎語法(五)繼承——萬字總結,干貨滿滿

    摘要:繼承方式繼承方式限定了基類成員在派生類中的訪問權限,包括公有的私有的和受保護的。所以子類給父類引用賦值也是可以的,相當于給子類對象中繼承的父類部分起了別名。如圖成員函數也是如此,當子類與父類具有函數名相同的函數時,還是符合就近原則。 ...

    smartlion 評論0 收藏0
  • JavaScript面向對象編程-繼承(三)

    摘要:子類不是父類實例的問題是由類式繼承引起的。所以寄生式繼承和構造函數繼承的組合又稱為一種新的繼承方式。但是這里的寄生式繼承處理的不是對象,而是類的原型。看上去略微復雜,還得好好研究。 寄生組合式繼承(終極繼承者) 前面學習了類式繼承和構造函數繼承組合使用,也就是組合繼承,但是這種繼承方式有個問題,就是子類不是父類的實例,而子類的原型是父類的實例。子類不是父類實例的問題是由類式繼承引起的。...

    alaege 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<