亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

深入JS繼承

 更新時間:2021年05月06日 09:17:34   作者:淺笑·  
這篇文章主要介紹了深入JS繼承,對繼承感興趣的同學(xué),可以參考下

前言

對于靈活的js而言,繼承相比于java等語言,繼承實現(xiàn)方式可謂百花齊放。方式的多樣就意味著知識點繁多,當然也是面試時繞不開的點。撇開ES6 class不談,傳統(tǒng)的繼承方式你知道幾種?每種實現(xiàn)原理是什么,優(yōu)劣點能談?wù)剢?。這里就結(jié)合具體例子,按照漸進式的思路來看看繼承的發(fā)展。

準備

談到j(luò)s繼承之前先回顧下js 實例化對象的實現(xiàn)方式。

構(gòu)造函數(shù)是指可以通過new 來實例化對象的函數(shù),目的就是為了復(fù)用,避免每次都手動聲明對象實例。

new 簡單實現(xiàn)如下:

function my_new(func){
    var obj = {}
    obj._proto_ = func.prototype // 修改原型鏈指向,拼接至func原型鏈
    func.call(obj) // 實例屬性賦值
    return obj
}

由上可以看出,通過構(gòu)造函數(shù)調(diào)用,可以將實例屬性賦值到目標對象上。

如此可以推想,子類中調(diào)用父類構(gòu)造函數(shù)同樣可以達到繼承的目的。

這就提供了js繼承的一種思路,即通過構(gòu)造函數(shù)調(diào)用。

至于原型屬性,就是通過修改原型指向,來實現(xiàn)原型屬性的共享。

那么繼承時同樣也可以通過該方式進行。

總結(jié)

基于構(gòu)造函數(shù)和原型鏈兩種特性,結(jié)合js語言的靈活性。

繼承的實現(xiàn)方式雖然繁多萬變也不離其宗

繼承的n種方式

原型式繼承

定義:這種繼承借助原型并基于已有的對象創(chuàng)建新對象,同時還不用創(chuàng)建自定義類型的方式稱為原型式繼承。

直接看代碼更清晰:

function createObj(o) {
  function F() { }
  F.prototype = o;
  return new F();
}
var parent = {
  name: 'trigkit4',
  arr: ['brother', 'sister', 'baba']
};
var child1 = createObj(parent);

該方式表面上看基于對象創(chuàng)建,不需要構(gòu)造函數(shù)(當然實際構(gòu)造函數(shù)被封裝起來罷了)。只借助了原型對象,所以名稱為原型式繼承。

缺點:

比較明顯優(yōu)良者

無法復(fù)用該繼承,每個子類的實例,都要走完整的createObj流程。

對于子類對象

因為構(gòu)造函數(shù)封裝createObj中,對其而言,沒有構(gòu)造函數(shù)。由此造成無法初始化時傳參。
補充:其中 createObj 就是我們ES6中常用的Object.create(),不過Object.create進行了完善,允許額外參數(shù)來完善了。

解決思路:

既然提到?jīng)]有構(gòu)造函數(shù)導(dǎo)致了問題,那么大膽猜測,更進一步就是涉及了構(gòu)造函數(shù)的原型鏈繼承了。

原型鏈式繼承

定義:為了讓子類繼承父類的屬性(也包括方法),首先需要定義一個構(gòu)造函數(shù)。然后,將父類的新實例賦值給構(gòu)造函數(shù)的原型。

function Parent() {
  this.name = 'mike';
}
function Child() {
  this.age = 12;
}
Child.prototype = new Parent();
child.prototype.contructor = child // 原型屬性被覆蓋,所以要修正回來。
var child1 = new Child();

也就是直接修改子類的原型對象指父構(gòu)造函數(shù)的實例,這樣把父類的實例屬性和原型屬性都掛到自己原型鏈上。

缺點

Child.prototype = new Parent() ,那么子函數(shù)自身的原型屬性就被覆蓋了,如果需要就要在后面補充。

子對象實例化時,無法向父類構(gòu)造函數(shù)傳遞參數(shù)。
例如在new Child()執(zhí)行的時候,想要去覆蓋name,只能在Child.prototype = new Parent()時。 是我們在new Child()的時候統(tǒng)一傳參初始化是更常規(guī)需求。

解決思路

如何在子類初始化時,調(diào)用父類構(gòu)造函數(shù)。結(jié)合前面的基礎(chǔ),答案也呼之欲出。

借用構(gòu)造函數(shù)(類式繼承)

類式繼承:是在子類型構(gòu)造函數(shù)的內(nèi)部調(diào)用超類型的構(gòu)造函數(shù)。

思路比較清晰,由問題驅(qū)動。

既然原型鏈式子類不能向父類傳參的問題,那么在子類初始化是調(diào)用父類不就滿足目的了。

示例如下:

function Parent(age) {
  this.name = ['mike', 'jack', 'smith'];
  this.age = age;
}
Parent.prototype.run = function () {
  return this.name + ' are both' + this.age;
};
function Child(age) {
  // 調(diào)用父類
  Parent.call(this, age);
}
var child1 = new Child(21);

這樣滿足了初始化時傳參的需求,但是問題也比較明顯。

child1.run //undefined

問題

父類原型屬性丟失

父類初始化只繼承了示例屬性,原型屬性在子類的原型鏈上丟失

解決思路

丟失的原因在于原型鏈沒有修改指向,那么修改下指向不就完了。

組合繼承

定義:使用原型鏈實現(xiàn)對原型屬性和方法的繼承,而通過借用構(gòu)造函數(shù)來實現(xiàn)對實例屬性的繼承

示例:

function Parent(age) {
  this.name = ['mike', 'jack', 'smith'];
  this.age = age;
}
Parent.prototype.run = function () {
  return this.name + ' are both' + this.age;
};
function Child(age) {
  // 調(diào)用父類構(gòu)造函數(shù)
  Parent.call(this, age);
}
Child.prototype = new Parent();//原型屬性繼承
Child.prototype.contructor = Child
var child1 = new Child(21);

這樣問題就避免了:

child1.run() // "mike,jack,smith are both21"

問題

功能滿足之后,就該關(guān)注性能了。這種繼承方式問題在于父類構(gòu)造函數(shù)執(zhí)行了兩次。

分別是:

function Child(age) {
  // 調(diào)用父類構(gòu)造函數(shù),第二次
  Parent.call(this, age);
}
Child.prototype = new Parent();//修改原型鏈指向,第一次

解決思路

解決自然是取消一次構(gòu)造函數(shù)調(diào)用,要取消自然要分析這兩次執(zhí)行,功能上是否有重復(fù)。

第一次同樣繼承了實例和原型屬性,第二次執(zhí)行同樣繼承了父類的實例屬性。

因此第二次滿足對父類傳參的不可獲取性,因此只能思考能否第一次不調(diào)用父類構(gòu)造函數(shù),只繼承原型屬性。

答案自然是能,前面原型式繼承就是這個思路。

寄生組合式繼承

顧名思義,寄生指的是將繼承原型屬性的方法封裝在特定方法中,組合的是將構(gòu)造函數(shù)繼承組合起來,補充原型式繼承的不足。

饒了點,直接看:

function createObj(o) {
  function F() { }
  F.prototype = o;
  return new F();
}
//繼承原型屬性 即原型式繼承
function create(parent, child) { 
  var f = createObj(parent.prototype);//獲取原型對象
  child.prototype = f
  child.prototype.constructor = child;//增強對象原型,即保持原有constructor指向
}

function Parent(name) {
  this.name = name;
  this.arr = ['brother', 'sister', 'parents'];
}
Parent.prototype.run = function () {
  return this.name;
};
function Child(name, age) {
  // 示例屬性
  Parent.call(this, name);
  this.age = age;
}
// 原型屬性繼承寄生于該方法中
create(Parent.prototype,Child);
var child1 = new Child('trigkit4', 21);

這樣沿著發(fā)現(xiàn)問題解決問題的思路直到相對完善的繼承方式。至于ES的方式本篇就不涉及了。

結(jié)束語

唯有厚積,才能薄發(fā),想要心儀的offer,就得準備充裕,夯實基礎(chǔ),切忌似是而非,道理我都懂就是答得不完全,這樣跟不懂差別也不太大。不算新的日子里立個flag,每周三個知識點回顧。要去相信,你若盛開蝴蝶自來。

以上就是深入JS繼承的詳細內(nèi)容,更多關(guān)于深入JS繼承的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • JS深度拷貝Object Array實例分析

    JS深度拷貝Object Array實例分析

    這篇文章主要介紹了JS深度拷貝Object Array,結(jié)合實例形式分析了JavaScript深度拷貝的原理,需要的朋友可以參考下
    2016-03-03
  • 優(yōu)雅而高效的JavaScript?try...catch語句詳解(js異常處理)

    優(yōu)雅而高效的JavaScript?try...catch語句詳解(js異常處理)

    這篇文章主要給大家介紹了關(guān)于JavaScript中try...catch語句的相關(guān)資料,也就是js異常處理方法,try...catch是JavaScript中的錯誤處理機制,它的作用是捕獲和處理可能發(fā)生的錯誤,以避免程序崩潰,需要的朋友可以參考下
    2024-01-01
  • js中的時間轉(zhuǎn)換—毫秒轉(zhuǎn)換成日期時間的示例代碼

    js中的時間轉(zhuǎn)換—毫秒轉(zhuǎn)換成日期時間的示例代碼

    本篇文章主要是對js中的時間轉(zhuǎn)換—毫秒轉(zhuǎn)換成日期時間的示例代碼進行了介紹,需要的朋友可以過來參考下,希望對大家有所幫助
    2014-01-01
  • 用Javascript 和 CSS 實現(xiàn)腳注(Footnote)效果

    用Javascript 和 CSS 實現(xiàn)腳注(Footnote)效果

    腳注(Footnote)是向用戶提供更多信息的一個最佳途徑,也是主體信息的一個有效補充,常見于各種印刷書籍中。
    2009-09-09
  • 為什么TypeScript的Enum會出現(xiàn)問題

    為什么TypeScript的Enum會出現(xiàn)問題

    TypeScript引入了很多靜態(tài)編譯語言的特性,今天有一個類型需要著重討論下,這就是enum,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-06-06
  • 異步安全加載javascript文件的方法

    異步安全加載javascript文件的方法

    這篇文章主要介紹了異步安全加載javascript文件的方法,實例分析了javascript實現(xiàn)文件異步加載的具體技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-07-07
  • js中的escape及unescape函數(shù)的php實現(xiàn)代碼

    js中的escape及unescape函數(shù)的php實現(xiàn)代碼

    js中的escape及unescape函數(shù)的php實現(xiàn)代碼...
    2007-09-09
  • Json格式詳解

    Json格式詳解

    JSON(JavaScript Object Notation) 是一種輕量級的數(shù)據(jù)交換格式。JSON采用完全獨立于語言的文本格式,這些特性使JSON成為理想的數(shù)據(jù)交換語言。易于人閱讀和編寫,同時也易于機器解析和生成
    2021-11-11
  • JS實現(xiàn)前端動態(tài)分頁碼代碼實例

    JS實現(xiàn)前端動態(tài)分頁碼代碼實例

    這篇文章主要介紹了JS實現(xiàn)前端動態(tài)分頁碼代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-06-06
  • JS實現(xiàn)簡單打字測試

    JS實現(xiàn)簡單打字測試

    這篇文章主要為大家詳細介紹了JS實現(xiàn)簡單打字測試,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-06-06

最新評論