摘要:中繼承比較復(fù)雜,坑比較多,最近有點(diǎn)時(shí)間整理下,記錄下來(lái)。的繼承實(shí)現(xiàn)方式大概分類如下的兩大類,每一種實(shí)現(xiàn)都有自己的有點(diǎn)和缺點(diǎn),根據(jù)場(chǎng)景選擇吧通過(guò)修改原型鏈來(lái)來(lái)實(shí)現(xiàn)繼承通過(guò)復(fù)制父類來(lái)來(lái)實(shí)現(xiàn)繼承為了理解繼承的原型鏈的變化,我畫了原型鏈圖。
JS 中繼承比較復(fù)雜,坑比較多,最近有點(diǎn)時(shí)間整理下,記錄下來(lái)。
JS 的繼承實(shí)現(xiàn)方式大概分類如下的兩大類,每一種實(shí)現(xiàn)都有自己的有點(diǎn)和缺點(diǎn),根據(jù)場(chǎng)景選擇吧
通過(guò)修改原型鏈來(lái)來(lái)實(shí)現(xiàn)繼承
通過(guò)復(fù)制父類來(lái)來(lái)實(shí)現(xiàn)繼承
為了理解繼承的原型鏈的變化,我畫了原型鏈圖。下圖是沒(méi)有繼承的時(shí)候,父類和子類的原型鏈圖
function Parent(name, age) { this.name = name; this.age = age; } Parent.prototype.getName = function () { return this.name; }; Parent.prototype.getAge = function () { return this.age; }; Parent.prototype.love = { game: ["DoTa"] }; Parent.pay = function(){ return 1000; }; function Son(){}修改原型鏈來(lái)來(lái)實(shí)現(xiàn)繼承
修改原型鏈也有好幾種,現(xiàn)在分開(kāi)來(lái)說(shuō):
第一種實(shí)現(xiàn)原理:修改原型鏈(子類的原型指向父類的原型)實(shí)現(xiàn)繼承
優(yōu)點(diǎn):簡(jiǎn)單
缺點(diǎn):子類修改影響父類
原型鏈圖注意里面的紅線
不調(diào)用構(gòu)造方法實(shí)現(xiàn)
function Son(){} Son.prototype = new Parent(); Son.prototype.constructor = Son;
調(diào)用構(gòu)造方法實(shí)現(xiàn)
function Son(){ Parent.apply(this, arguments) } Son.prototype = Parent.prototype; Son.prototype.constructor = Son;
詳細(xì)代碼實(shí)現(xiàn):https://github.com/xuanxiao2013/f2e-practice/blob/master/javascript-inherit/inherit1.js
第二種實(shí)現(xiàn)原理:修改原型鏈(通過(guò)加入臨時(shí)函數(shù),阻止子類修改父類)實(shí)現(xiàn)繼承
優(yōu)點(diǎn):子類即能繼承父類,又基本不影響父類,達(dá)到真正意義上的繼承
缺點(diǎn):實(shí)例的對(duì)象和父類原型的對(duì)象相同的時(shí)候(父類的love),可能會(huì)出現(xiàn)子類修改父類對(duì)象原型中的所有屬性被實(shí)例共享,共享很適合函數(shù),對(duì)基本值的屬性也可以(實(shí)例上添加同名屬性),但是對(duì)引用類型的值的屬性來(lái)說(shuō),就會(huì)有問(wèn)題
原型鏈圖注意里面的紅線
ES3 實(shí)現(xiàn)方式詳細(xì)代碼實(shí)現(xiàn):
function create(proto){ var F = function(){}; F.prototype = proto; return new F(); } function Son(){ Parent.apply(this, arguments); } Son.prototype = create(Parent.prototype); Son.prototype.constructor = Son;
ES5 實(shí)現(xiàn)方式詳細(xì)代碼實(shí)現(xiàn):
function Son(){ Parent.apply(this, arguments); } Son.prototype = Object.create(Parent.prototype) Son.prototype.constructor = Son;
ES6 實(shí)現(xiàn)方式 詳細(xì)代碼實(shí)現(xiàn):
class Parent{ constructor(name, age){ this.name = name; this.age = age; } } Parent.prototype.getName = function () { return this.name; }; Parent.prototype.getAge = function () { return this.age; }; Parent.prototype.love = { game: ["DoTa"] }; class Son extends Parent { constructor(...args){ super(...args); } }
都說(shuō)ES6 的Class 只是個(gè)語(yǔ)法糖,看來(lái)原因在這了
測(cè)試:
var parent = new Parent("jack", 40); log("parentName:" + parent.getName()); // parentName:jack var son = new Son("tom", 20); Son.prototype.getName = function(){ return this.name + " has good father"; }; log("sonName:" + son.getName()); // sonName:tom has good father log("parentName:" + parent.getName()); // parentName:jack log(Son.prototype.constructor === Son); // true log(son instanceof Son); // true log(son instanceof Parent); // true log(son instanceof Object); // true log("parent love:" + parent.love.game); // parent love:DoTa log("son love:" + son.love.game); // son love:DoTa log("------------------------"); // 注意這里 son.love.game = "DoTa2"; log("parent love:" + parent.love.game); // parent love:DoTa2 log("son love:" + son.love.game); // son love:DoTa2 log("------------------------"); son.love = { game: "DoTa3" }; // 注意這里 log("parent love:" + parent.love.game); // parent love:DoTa2 log("son love:" + son.love.game); // son love:DoTa3復(fù)制父類來(lái)來(lái)實(shí)現(xiàn)繼承
實(shí)現(xiàn)原理:通過(guò)深度復(fù)制把父類的方法復(fù)制一份給子類來(lái)實(shí)現(xiàn)繼承
優(yōu)點(diǎn):子類即能繼承父類,又不影響父類,達(dá)到真正意義上的繼承
缺點(diǎn):復(fù)雜
詳細(xì)代碼實(shí)現(xiàn):https://github.com/xuanxiao2013/f2e-practice/blob/master/javascript-inherit/inherit3.js
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/86216.html
摘要:巧前端基礎(chǔ)進(jìn)階全方位解讀前端掘金我們?cè)趯W(xué)習(xí)的過(guò)程中,由于對(duì)一些概念理解得不是很清楚,但是又想要通過(guò)一些方式把它記下來(lái),于是就很容易草率的給這些概念定下一些方便自己記憶的有偏差的結(jié)論。 計(jì)算機(jī)程序的思維邏輯 (83) - 并發(fā)總結(jié) - 掘金從65節(jié)到82節(jié),我們用了18篇文章討論并發(fā),本節(jié)進(jìn)行簡(jiǎn)要總結(jié)。 多線程開(kāi)發(fā)有兩個(gè)核心問(wèn)題,一個(gè)是競(jìng)爭(zhēng),另一個(gè)是協(xié)作。競(jìng)爭(zhēng)會(huì)出現(xiàn)線程安全問(wèn)題,所以,本...
摘要:巧前端基礎(chǔ)進(jìn)階全方位解讀前端掘金我們?cè)趯W(xué)習(xí)的過(guò)程中,由于對(duì)一些概念理解得不是很清楚,但是又想要通過(guò)一些方式把它記下來(lái),于是就很容易草率的給這些概念定下一些方便自己記憶的有偏差的結(jié)論。 計(jì)算機(jī)程序的思維邏輯 (83) - 并發(fā)總結(jié) - 掘金從65節(jié)到82節(jié),我們用了18篇文章討論并發(fā),本節(jié)進(jìn)行簡(jiǎn)要總結(jié)。 多線程開(kāi)發(fā)有兩個(gè)核心問(wèn)題,一個(gè)是競(jìng)爭(zhēng),另一個(gè)是協(xié)作。競(jìng)爭(zhēng)會(huì)出現(xiàn)線程安全問(wèn)題,所以,本...
摘要:今天同事小英童鞋問(wèn)了我一個(gè)問(wèn)題小英童鞋認(rèn)為的原型對(duì)象是,所以會(huì)繼承的屬性,調(diào)用相當(dāng)于調(diào)用,但結(jié)果不是一個(gè)方法。構(gòu)造函數(shù)創(chuàng)建對(duì)象實(shí)例函數(shù)有兩個(gè)不同的內(nèi)部方法和。如果不通過(guò)關(guān)鍵字調(diào)用函數(shù),則執(zhí)行函數(shù),從而直接執(zhí)行代碼中的函數(shù)體。 今天同事小英童鞋問(wèn)了我一個(gè)問(wèn)題: function Foo(firstName, lastName){ this.firstName = firstNam...
摘要:本文是面向前端小白的,大手子可以跳過(guò),寫的不好之處多多分鐘搞定常用基礎(chǔ)知識(shí)前端掘金基礎(chǔ)智商劃重點(diǎn)在實(shí)際開(kāi)發(fā)中,已經(jīng)非常普及了。 JavaScript字符串所有API全解密 - 掘金關(guān)于 我的博客:louis blog SF專欄:路易斯前端深度課 原文鏈接:JavaScript字符串所有API全解密 本文近 6k 字,讀完需 10 分鐘。 字符串作為基本的信息交流的橋梁,幾乎被所有的編程...
摘要:前言本章我們要講解的是五大原則語(yǔ)言實(shí)現(xiàn)的第篇,里氏替換原則。因此,違反了里氏替換原則。與行為有關(guān),而不是繼承到現(xiàn)在,我們討論了和繼承上下文在內(nèi)的里氏替換原則,指示出的面向?qū)ο蟆? 前言 本章我們要講解的是S.O.L.I.D五大原則JavaScript語(yǔ)言實(shí)現(xiàn)的第3篇,里氏替換原則LSP(The Liskov Substitution Principle )。英文原文:http://fre...
閱讀 2251·2021-11-24 09:38
閱讀 3333·2021-11-08 13:27
閱讀 3153·2021-09-10 10:51
閱讀 3276·2019-08-29 12:20
閱讀 728·2019-08-28 18:28
閱讀 3518·2019-08-26 11:53
閱讀 2775·2019-08-26 11:46
閱讀 1587·2019-08-26 10:56