JavaScript必知的特性(繼承)

多數(shù)人在學(xué)習(xí)JavaScript的時候,都是做Web的時候,需要表單驗證,或者是一些簡單的DOM操作,如同我上篇所講,處在一個“輔助”的地位。

處在“輔助”地位的JavaScript,我們總是抱著解決問題就行的態(tài)度,自然不會關(guān)注其過多的特性。那么,今天我們就來聊聊在開發(fā)中有哪些特性是我們必須要了解的!

?

JavaScript的結(jié)構(gòu)

JavaScript分為三個部分

ECMAScript ?JavaScript本身的語法

DOM ?全稱Document Object Model ,針對HTML Document操作的API,例如document.getElementByID

BOM ?全稱Browser Object Model,針對瀏覽器Window操作的API,例如window.location

在一般的項目中,多數(shù)人會關(guān)注DOM操作,所以忽略了JavaScript語法本身的精髓。我們今天重點關(guān)注的就是:JavaScript本身語法。

請注意:我們在前端使用JavaScript時,多數(shù)是以操作DOM為目的,學(xué)習(xí)JavaScript語言的精髓,本身就是為了讓我們更優(yōu)雅的“操作DOM”!

由于JS的每一個特性都包含太多內(nèi)容,所以我們只能分多篇來講,今日我們先講繼承!我對于繼承的講解方法會和百度的帖子迥異,但更通俗一些,希望大家看過之后可以秒懂“繼承”。

面向?qū)ο蟮娜笤瓌t:封裝,繼承,多態(tài)。我們不能脫離其他法則單講繼承,封裝是繼承的先決條件,多態(tài)是繼承要達到的目的,三者是糾合在一起的!

1. 封裝

封裝是對象的表現(xiàn)形式。比如Java中,封裝的表現(xiàn)形式是JavaBean,在JavaScript就是Object,通俗點就是{}

我們來看JavaScript的一個簡單對象


對象的兩個要點:屬性和行為, name作為屬性,work作為行為,已經(jīng)滿足封裝的基本要素,所以我們認定student是一個對象。它的對象就是如此簡單。

我們這里多插一個知識點:對象和我們平時講的JSON,有什么不同呢?

JSON是JavaScript對象標記語言,JSON的作用是數(shù)據(jù)傳輸,“數(shù)據(jù)”具有不可變性,所以JSON只能包含屬性,不能有行為。即:JSON中沒有任何JavaScript方法!它們的區(qū)別就在于有沒有包含方法。


要記住JSON和對象的區(qū)別,只要我們記住一句繞口令即可:JSON一定是JavaScript對象,JavaScript對象不一定是JSON!

2. 繼承

所有的JavaScript的對象,在其生成的時候,編譯器都會附加給對象一個特殊的屬性:prototype,即大家常說的原型。理解原型是理解JavaScript繼承的重點。

原型有一個最最最重要的特點: 強單例 。同一類型的對象擁有的原型是一個,比如Array,所有的Array實例的原型只有一個!

下面的代碼中,arr1和arr2的prototype指向的是同一個,如果設(shè)置arr1的為null,arr2的也就為null了。


我們在看JavaScript的API時,經(jīng)常看到Array的方法有:push shift slice splice等等,這些方法都是存在Array的prototype中。

我們再來看看,當我們調(diào)用一個JavaScript對象方法的時候,它的解析器是如何工作的?

例如調(diào)用arr1.push 方法,

1. 解析器會首先遍歷“對象本身”的方法,如果找到,則直接調(diào)用,否則,繼續(xù)第二步驟

2. 解析器會查看對象的Prototype對象中是否存在該方法,存在則調(diào)用,不存在就拋出Exception

講到這里,大家應(yīng)該秒懂“Prototype”是個什么東西了吧! 其實就是給對象附加一個內(nèi)部對象而已,這個內(nèi)部對象又是一個單例的。作為單例,相對于對象本身肯定高效率的! 但是也是危險的??!

比如剛才我賤賤的設(shè)置arr1的prototype為null,那完蛋了??!整個頁面的Array都要出錯!如果我這樣修改,估計有些不明所以的程序員都要哭了,尼瑪瀏覽器會罵人!


看過以上,請大家記?。好總€JavaScript對象都分為兩個部分:“本身”和prototype。那么對象的繼承也是針對這兩個部分展開的。繼承的目的是為了擴展,說更通俗點就是,為了給某個對象附加更多的方法。

這時候問題就回歸為,如何給JavaScrit對象附加方法?

針對本身附加

上面的student,這時候又來了小明同學(xué),但是小明同學(xué)比Aric多了一項技能,會擼呀擼! 要如何實現(xiàn)呢?


jquery的extend的原理就是把一個對象的所有屬性和方法附加到另外一個上面!

針對prototype附加

如果上面代碼修改為:小明.prototype.lol = func...這樣也實現(xiàn)了同樣的功能,但是這時候Aric也有了LOL這個功能!

百度上多數(shù)講繼承的帖子,都會有如下這樣的偽代碼, 我們看過以上文章,是不是就明白了為什么! 我曾經(jīng)看過無數(shù)的繼承的帖子,一直也不懂prototype是個什么玩意!!

關(guān)于繼承的使用,這里基本落幕,大家心中都應(yīng)該有一個初步的印象了。當你懂的事物的原理后,再學(xué)習(xí)起來應(yīng)該就更加得心應(yīng)手了。

3. 多態(tài)

面向?qū)ο蟮娜笤瓌t之一:多態(tài)。多態(tài)分為對象多態(tài)和方法多態(tài)! 這是兩個不同的概念。

對象多態(tài)

就是我們時??吹降呢埞范紝儆趧游铮埥惺沁鬟?,狗卻是汪汪,這是多態(tài)的最直接體現(xiàn)。至于更多實現(xiàn)細節(jié),請大家自行百度。

方法多態(tài)

方法多態(tài),就是方法名字相同,但是傳入的參數(shù)列表不同!這個在Java或者C#中都被我們玩爛了! 在JavaScript中由于沒有參數(shù)列表,一般都用方法的內(nèi)部函數(shù)Arguments來表述!Arguments是偽Array,里面放的就是當前方法的參數(shù)列表!

具體使用過程中,即可通過Arguments中元素的個數(shù)來實現(xiàn)方法多態(tài)。

很多人都說JavaScript不是面向?qū)ο蟮木幊陶Z言,其實是對JavaScript的誤解!面向?qū)ο蟮娜笤瓌t,JavaScript都能實現(xiàn)!只是實現(xiàn)的方式有些不同,卻有異曲同工之妙。


說在最后的話:

JavaScript的繼承不像Java那樣有明確的語法規(guī)則,它是靈活多變的。所以寫慣Java這種類型的人員,非常討厭其語法,我在剛?cè)腴T時,也是如此。但是在當你掌握了它,它的靈活多變會變成編程中的利器,劍之所指,所向披靡!

希望每一位有心學(xué)習(xí)JavaScript的程序員,都能理解其繼承原理!

接下來,我們會繼續(xù)講解JavaScript的其他特性!在講解這些特性的同時,我會結(jié)合其一些知名類庫,比如jQuery,講解這些特性在其中的應(yīng)用。

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

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

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