面向?qū)ο螅ㄔ?構(gòu)造函數(shù))-面向?qū)ο蟾呒?7種繼承-學習總結(jié)

首先要了解一下面向?qū)ο蟮母拍睿?/p>

JS是一種基于對象的語言,和其它面向?qū)ο笳Z言不同

對象

一.如何創(chuàng)建一個對象:

第一種方法:創(chuàng)建對象的方式:

?var obj = new Object(); 利用new實例化出一個obj對象;

里面的屬性和方法可以自定義

創(chuàng)建obj對象

第二種用字面量的方式:直接設(shè)置一個obj,在里面設(shè)置屬性和值;

設(shè)置一個obj

工廠模式

軟件工程領(lǐng)域的一種設(shè)計模式,抽象了創(chuàng)建對象的過程,通過函數(shù)封裝創(chuàng)建對象的細節(jié):

工廠模式

這種方法比較簡單明了并且動態(tài),但是也有弊端

1.看不出類型(如果比如寫的是new的別的對象,那么其實也可以執(zhí)行,也可以打印出來,很容易造成錯誤)

===》解決方法:構(gòu)造函數(shù);

2.函數(shù)重復、浪費資源 (利用傳參的方式,每次寫一次,函數(shù)就要執(zhí)行一次,會造成服務器壓力大)

===》解決方法:原型;


構(gòu)造函數(shù)怎么寫:

構(gòu)造函數(shù)一般以大寫字母開頭

構(gòu)造函數(shù)也是函數(shù),只不過可以用來創(chuàng)建對象

與工廠模式對比,沒有顯式創(chuàng)建對象,直接將屬性和方法賦給了this對象,沒有return

構(gòu)造函數(shù)

原型:prototype 是指原型 原型本身就是一個對象,因此我們只是在原型對象里創(chuàng)造了一個方法

原型:prototype

★推薦使用原型+構(gòu)造函數(shù)結(jié)合的方法,既可以解決看不出類型的問題,又可以解決重復函數(shù)執(zhí)行,浪費資源;

★在原型上寫的新的方法,方法名不要和原來就有的方法重名,不然會產(chǎn)生覆蓋;(比如trim)

我們已知trim方法可以去除前后的空格,那么我們?yōu)槭裁催€要用正則,而不直接使用trim呢?

因為trim有兼容問題,(trim有trimRight 、trimLeft、trimStart、trimEndie11不兼容;?本身的trim兼容):


面向?qū)ο蟾呒墸?br>

如何繼承:

用原型繼承鏈 prototype:(這個不是直接繼承):

用原型繼承鏈 prototype:

??但是會有一個問題,本來的原型被覆蓋了,那么我們怎么辦?

我們需要手動添加他的本來一個原型:構(gòu)造函數(shù).prototype.constructor =構(gòu)造函數(shù)本身;

構(gòu)造函數(shù).prototype.constructor =構(gòu)造函數(shù)本身

原型鏈繼承-直接繼承prototype:

對上一種方法的改進

由于Person對象中,不變的屬性都可以直接寫入Person.prototype。所以,可以讓Man()跳過 Person(),直接繼承Person.prototype;

優(yōu)點:效率比較高(不用執(zhí)行和建立Person的實例了)

缺點:Man.prototype和Person.prototype現(xiàn)在指向了同一個對象,任何對Man.prototype的修改,都會反映到Person.prototype

原型鏈繼承-直接繼承prototype

利用空對象作為中介:其實這幾種方法就是在進行一步又一步的優(yōu)化:

空對象的好處:既可以繼承,但是又不會影響子類的原型;

利用空對象作為中介

然后再精簡化一下,把空對象函數(shù)封裝一下:

把空對象函數(shù)封裝

構(gòu)造函數(shù)綁定:掌握構(gòu)造函數(shù)綁定實現(xiàn)繼承,改變this的指向:

1.用call的方法:

用call的方法

2.用apply的方法:apply的方法和call方法是一樣的,只是call一個一個傳遞的,而apply需要用數(shù)組的方式來傳遞;

用apply的方法

3.用bind方法來改變this執(zhí)行:

bind方法執(zhí)行完返回的是一個函數(shù),

想要執(zhí)行,就要加括號去執(zhí)行

?添加參數(shù)的第一種方法: obj1.fn.bind(obj2)("愛釣魚","愛看手機")?

添加參數(shù)的第二種方法: obj1.fn.bind(obj2,"愛釣魚","愛看手機")()?

那么bind和apply還有call有什么區(qū)別呢?:返回的是一個函數(shù);

bind

通過call方法掌握構(gòu)造函數(shù)綁定實現(xiàn)繼承:

call方法

通過apply的方法掌握構(gòu)造函數(shù)綁定實現(xiàn)繼承:

通過apply的方法

通過bind方法掌握構(gòu)造函數(shù)綁定實現(xiàn)繼承:

通過bind方法

組合繼承:

也叫偽經(jīng)典繼承:將原型鏈繼承和構(gòu)造函數(shù)繼承組合在一塊

利用call/apply/bind只能繼承父類實例屬性的繼承,不能繼承父類原型上的屬性和方法,所以要借助于原型鏈繼承;

組合繼承

拷貝繼承:

把父對象的所有屬性和方法,拷貝進子對象

拷貝繼承

ES6的繼承方式:class的繼承:

ES6繼承實際上是一種語法糖,底層就是原型鏈繼承==通過new父類的實例給到子類的原型上

父類 可以把構(gòu)造函數(shù)為類class,利用構(gòu)造器constructor來傳遞參數(shù),或設(shè)置自身的屬性和方法,不需要寫function,子類 ?子類繼承父類 通過關(guān)鍵詞 extends實現(xiàn),利用super關(guān)鍵字來調(diào)用父類的構(gòu)造函數(shù),super就代表父類;

ES6的繼承方式:class的繼承


ps:我們可以通過使用instanceof的方法,來判斷實例是哪一個類的實例,如果屬于,返回true,不屬于返回false

原型鏈繼承的方式:子類的實例是屬于父類的

拷貝以及構(gòu)造函數(shù)(call,apply,bind)的方式:子類的實例是不屬于父類的

instanceof的方法檢查
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容