關於繼承網上有很多文章,但是能講解的大多都不讓我滿意,所以自己寫一篇。本文適合已經知道js繼承的各種或部分方式,但是尚未形成系統脈絡的讀者。
接下來為方便描述,約定:a是父類,a是a類的例項,b是子類,b是b類的例項。
b.prototype = a;
這種繼承的潛在問題是,將a的例項屬性變成了原型上的屬性。如果某乙個屬性是引用型別,那麼所有的b 都將共用乙個引用,改變乙個b,所有的b都跟著變。
問題示例:
functiona()}
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會共享。
functionb()
這種繼承問題很明顯:無法繼承a的原型上的方法。
functionb()
b.prototype =a;
b.prototype.constructor = b;
這種方式接近完美:屬性不會被共享,同時原型上的方法也繼承過來了。
美中不足的是 b.prototype = a; 這一行,a的例項屬性會汙染b的原型,成為永遠不能被b訪問到的 卻額外占用了記憶體的垃圾。
組合的公升級 :
functionb()
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;
functionb()
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...