幫你理清js的繼承

2022-06-17 10:24:08 字數 1935 閱讀 9450

關於繼承網上有很多文章,但是能講解的大多都不讓我滿意,所以自己寫一篇。本文適合已經知道js繼承的各種或部分方式,但是尚未形成系統脈絡的讀者。

接下來為方便描述,約定:a是父類,a是a類的例項,b是子類,b是b類的例項。

b.prototype = a;

這種繼承的潛在問題是,將a的例項屬性變成了原型上的屬性。如果某乙個屬性是引用型別,那麼所有的b 都將共用乙個引用,改變乙個b,所有的b都跟著變。

問題示例:

function

a()}

b1.objfroma.name='b1'console.log( b2.objfroma.name )

//變成了b1

至於網上說的原型式繼承、寄生式繼承,其實都是這種方式的另一種寫法。

//

object.create 原型鏈繼承

let b1 =object.create(a);

let b2 =object.create(a);

//寄生式繼承

//我實在看不出來寄生式繼承和原型繼承有啥差別,玩概念而已,解決不了任何問題。這種繼承就不說了。

當然你還可以用 object.setprototypeof 實現原型繼承:

let b={}

object.setprototypeof(b,a)

//比object.create多寫一行,較麻煩。

這些所有的實現方式,本質都是原型鏈繼承,其潛在問題都是一樣的:例項屬性變成了原型上的屬性,如果是引用型別屬性的話,多個b會共享。

function

b()

這種繼承問題很明顯:無法繼承a的原型上的方法。

function

b()

b.prototype =a;

b.prototype.constructor = b;

這種方式接近完美:屬性不會被共享,同時原型上的方法也繼承過來了。

美中不足的是  b.prototype = a;  這一行,a的例項屬性會汙染b的原型,成為永遠不能被b訪問到的 卻額外占用了記憶體的垃圾。

組合的公升級 :

function

b()

b.prototype = object.create(a.prototype); //

不產生例項a,從而避免了產生垃圾

b.prototype.constructor = b;

大多數文章都是到此為止了,但這個方案還是由缺陷。

潛在問題一:a的靜態方法無法被繼承

靜態方法是直接寫在a上的,所以也要將a上的成員(注意是a不是a)繼承到b上(注意是b不是b)。

//

方法一:

object.assign(b,a) //

這種方法存在問題:如果a的靜態成員是變化的,b將無法跟隨變化

//方法二:

object.setprototypeof(b, a); //

這是完美的方法

潛在問題二:有時建構函式會返回乙個物件,而不是通過操作this。所以 a.call(this); 這一句也許並不能繼承a的例項成員。稍加改造:

let _this = a.call(this) || this

;

return _this;

function

b()

object.setprototypeof(b, a);

b.prototype =object.create(a.prototype);

b.prototype.constructor = b;

當你嘗試用es6的class繼承時 class b extends a 你會發現它最終會被babel翻譯成上面這個完美的方案。

幫你理清微信電商的思路

前幾天閒來無事,和研究員一起喝茶論道,討論微信電商。七哥 我剛看到個段子,是這樣的 目前關於微信電商概念有,微信小店 拍拍微店 京東微店 微信 微 微購物 微生活 微商戶 微支付 微 第三方微 二級網域名稱嫁接微信 微店。以上概念你全部分得清楚,你就是微信電商的專家了。你分得清楚嗎?研究員 分不清楚...

理清知識的脈絡

正因為mfc是建立在c 的基礎上,所以我強調c c 語言基礎對開發的重要性。技術的脈絡是有跡可循的,按照這個脈絡和規律走起來會省力一些 了解了windows的訊息機制在加上對訊息對映的理解就很容易了解mfc開發的基本思路了。打蛇打七寸,不要眉毛鬍子一把抓,抓住主要矛盾 主席的話值得思考 在1999 ...

JS的繼承方式

js繼承有5種實現方式 1 繼承第一種方式 物件冒充 function parent username function child username,password var parent new parent zhangsan var child new child lisi 123456 pa...