JavaScript繼承

面向對象與基于對象

在傳統面向對象的語言中,有兩個非常重要的概念 - 類和實例。 類定義了一類事物公共的行為和方法;而實例則是類的一個具體實現。 我們還知道,面向對象編程有三個重要的概念 - 封裝、繼承和多態。

但是在JavaScript的世界中,所有的這一切特性似乎都不存在。 因為JavaScript本身不是面向對象的語言,而是基于對象(原型)的語言。 這里面就有一些有趣的特性,比如JavaScript中所有事物都是對象, 包括字符串、數組、日期、數字,甚至是函數,比如下面這個例子:

pic-1.png

模擬JavaScript中類和繼承

在面向對象的語言中,我們使用類來創建一個自定義對象。然而JavaScript中所有事物都是對象,那么用什么辦法來創建自定義對象呢?
這就需要引入另外一個概念 - 原型(prototype),我們可以簡單的把prototype看做是一個模版,新創建的自定義對象都是這個模版(prototype)的一個拷貝 (實際上不是拷貝而是鏈接,只不過這種鏈接是不可見,給人們的感覺好像是拷貝)。
讓我們看一下通過prototype創建自定義對象的一個例子:

pic-2.jpg

當代碼var zhang = new Person("ZhangSan", "man")執行時,其實內部做了如下幾件事情:

  1. 創建一個空白對象(new Object())。
  2. 拷貝Person.prototype中的屬性(鍵值對)到這個空對象中(我們前面提到,內部實現時不是拷貝而是一個隱藏的鏈接)。
  3. 將這個對象通過this關鍵字傳遞到構造函數中并執行構造函數。
  4. 將這個對象賦值給變量zhang。

為了證明prototype模版并不是被拷貝到實例化的對象中,而是一種鏈接的方式,請看如下代碼:

pic-3.jpg

這種在JavaScript內部實現的隱藏的prototype鏈接,是JavaScript賴以生存的溫潤土壤, 也是模擬實現繼承的基礎。

如何在JavaScript中實現簡單的繼承? 下面的例子將創建一個雇員類Employee,它從Person繼承了原型prototype中的所有屬性。

pic-4.jpg

上面關于繼承的實現很粗糙,并且存在很多問題:

  1. 在創建Employee構造函數和原型(以后簡稱類)時,就對Person進行了實例化,這是不合適的。
  2. Employee的構造函數沒法調用父類Person的構造函數,導致在Employee構造函數中對name和sex屬性的重復賦值。
  3. Employee中的函數會覆蓋Person中的同名函數,沒有重載的機制(和上一條是一個類型的問題)。
  4. 創建JavaScript類的語法過于零散,不如C#/Java中的語法優雅。
  5. 實現中有constructor屬性的指向錯誤。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • JavaScript - 繼承和類 在這一篇中,我要聊聊 JavaScript 中的繼承和“類”。 首先跟你請教下...
    NARUTO_86閱讀 296評論 0 2
  • 之前的JavaScript繼承一文中已經介紹了繼承,但那篇只能算簡介。本篇結合原型鏈詳細介紹一下JavaScrip...
    張歆琳閱讀 2,614評論 0 8
  • 例子 我們生成兩個構造函數,后面的例子都是讓‘’貓‘’繼承‘’動物‘’的所有屬性和方法。 動物(為了更好的理解各種...
    流光號船長閱讀 340評論 0 1
  • 今晚一場心靈的大餐在不知不覺中展開了,原本沈重的開場,讓人覺得流程化的講講就很好,工作講到位就可以了。因為在贏家已...
    好彩妹閱讀 241評論 0 0
  • 螞蟻要爬出去 它也老大不小了 麻雀一定在笑它 看上去很費力 其實還沒爬過一朵花 誰知道它有沒有偷懶呢
    Ysisys閱讀 172評論 0 0