摘要:是基于原型鏈繼承的,但是其詭異的寫(xiě)法可能讓好多初學(xué)者望而卻步。在我們有和,很容易切換上下文,將各種互不相干糅合,達(dá)到的目的。最近在讀這本書(shū),有一些好的內(nèi)容,正好可以跟大家分享,但并不是全部,有興趣的同學(xué)也可以自己讀一下,請(qǐng)支持正版。
剛開(kāi)始,代碼只是代碼而已。當(dāng)代碼多了,我們發(fā)明了函數(shù),以便代碼可以重用。到后來(lái),我們的函數(shù)也越來(lái)越多,所以我們又發(fā)明了別的一些編程概念。但是當(dāng)我們沉迷于這些新概念的同時(shí),我們可能就錯(cuò)過(guò)了一些近在眼前的美麗事物……
類(lèi)繼承類(lèi)概念主要存在于面向?qū)ο缶幊讨械模赡艽蠹疑蠈W(xué)時(shí)都學(xué)過(guò),比如Java、C#、Objective-C等面向?qū)ο笳Z(yǔ)言。每個(gè)實(shí)體都需要先要有一個(gè)類(lèi),這個(gè)類(lèi)對(duì)于我們來(lái)說(shuō)是比較抽象的(不是說(shuō)abstract class哦),然后子類(lèi)還可以繼承父類(lèi)。
這感覺(jué)似乎有點(diǎn)亞里士多德形而上學(xué)和分類(lèi)法的味道,但簡(jiǎn)單來(lái)說(shuō)這就是面向?qū)ο蟮幕A(chǔ),在寫(xiě)出實(shí)際代碼之前,你得先寫(xiě)出一些類(lèi)、接口,然后類(lèi)繼承類(lèi)、類(lèi)實(shí)現(xiàn)接口……
實(shí)際上我們?nèi)祟?lèi)并不是非常擅長(zhǎng)分類(lèi),打個(gè)比方,一個(gè)按鈕(Button),它應(yīng)該是一個(gè)矩形(Rectangle),還是一個(gè)控件(Control)呢?我們可以讓Button繼承Rectangle,讓Rectangle繼承Control……等等,是不是有什么不對(duì)?
所以,面向?qū)ο蟮母拍羁赡軙?huì)在項(xiàng)目剛開(kāi)始時(shí)就把你壓垮,但這并不是說(shuō)面向?qū)ο缶筒缓茫皇怯袝r(shí)候并不適合你的項(xiàng)目。
原型鏈繼承可能大家都知道,JavaScript是不支持class關(guān)鍵字的,因?yàn)镴avaScript本身就不作為一個(gè)面向?qū)ο笳Z(yǔ)言來(lái)設(shè)計(jì),但并不妨礙大家想出各種招來(lái)實(shí)現(xiàn)class。
JavaScript是基于原型鏈(Prototype)繼承的,但是其詭異的寫(xiě)法可能讓好多初學(xué)者望而卻步。
function Circle() { this.radius = 7; } Circle.prototype = { area: function () { return Math.PI * this.radius * this.radius; }, grow: function () { this.radius++; }, shrink: function () { this.radius--; } };
在ES5之后,我們有了Object.create方法,好理解了一些。
var circle = Object.create({ area: function () { return Math.PI * this.radius * this.radius; }, grow: function () { this.radius++; }, shrink: function () { this.radius--; } }, { radius: { writable: true, configurable: true, value: 7 } });
只是第二參數(shù)用起來(lái)有點(diǎn)復(fù)雜,其實(shí)就是跟Object.defineProperties()的參數(shù)一樣,但是我們現(xiàn)在又有了ES6呀:
class Cicle { constructor() { this.radius = 7; } area() { return Math.PI * this.radius * this.radius; } grow() { this.radius++; } shrink() { this.radius--; } }
這都是一些使用JavaScript實(shí)現(xiàn)class的例子,實(shí)際上,JavaScript還可以有另外一種重用代碼的方式——Mixins。
Mixins這就是我們今天的主題,近在眼前的美麗事物,但可不是什么新概念,用過(guò)Ruby或Python的同學(xué),可能有所耳目,Mixins的字面意思就是把東西摻合在一起。
在JavaScript我們有call和apply,很容易切換上下文,將各種互不相干糅合,達(dá)到Mixins的目的。
假設(shè)我們要做一個(gè)圓形按鈕(RoundButton),它有兩個(gè)特性:
是圓的
可點(diǎn)擊
我們可以把這兩個(gè)特性分別寫(xiě)做2個(gè)函數(shù):
// 是圓的 var withCircle = function () { this.area = function () { return Math.PI * this.radius * this.radius; }; this.grow = function () { this.radius++; }; this.shrink = function () { this.radius--; } } // 可點(diǎn)擊 var withClickable = function () { this.hover = function () { console.log("hovering"); }; this.press = function () { console.log("button pressed"); }; this.release = function () { console.log("button released"); }; this.fire = function () { this.action.fire(); }; }
這是我們的圓形按鈕:
var RoundButton = function(radius, label, action) { this.radius = radius; this.label = label; this.action = action; };
現(xiàn)在我們要讓給這個(gè)圓形按鈕附上那兩個(gè)特性:
withCircle.call(RoundButton.prototype); withClickable.call(RoundButton.prototype); var button = new RoundButton(4, "yes!", function() { return "you said yes!" }); button1.fire(); // 輸出 "you said yes!"
這樣寫(xiě),是不是瞬間顯得既簡(jiǎn)潔又自然?讓人一眼看懂代碼在做什么。
當(dāng)然這些附加特性的函數(shù)用的多了,也就創(chuàng)建了許多函數(shù),這里可以簡(jiǎn)單的用一個(gè)立即執(zhí)行函數(shù)(Immediately Invoked Function Expression)的閉包來(lái)對(duì)其進(jìn)行優(yōu)化一下,以withCircle為例:
var withCircle = (function () { function area() { return Math.PI * this.radius * this.radius; } function grow() { this.radius++; } function shrink() { this.radius--; } return function () { this.area = area; this.grow = grow; this.shrink = shrink; }; })();
這樣就不需要每次使用都新建函數(shù)了,從而節(jié)省更多的資源。
Advice有時(shí)候,你無(wú)法確保某些函數(shù)可能會(huì)覆蓋原有的功能,例如以下例子:
Button.prototype.press = function() { console.log("pressed"); }; // 這時(shí)再用我們的 withClickable,就會(huì)覆蓋掉 press withClickable.call(Button.prototype);
這時(shí)候我們應(yīng)該采用Advice,Twitter的Flight框架已經(jīng)提供了此功能:
var withClickable = function () { this.after("press", function () { console.log("press again."); }); }; withAdvice.call(Button.prototype); withClickable.call(Button.prototype); var button = new Button(); button.press(); // 輸出 "pressed", "press again."
兩個(gè)press并不會(huì)互相沖突,而是有先后順序的執(zhí)行,就類(lèi)似通過(guò)addEventListener添加了多個(gè)事件而不是直接修改onclick一樣,具體細(xì)節(jié)可以參考Flight的API。
小結(jié)作為一名程序員,我們或許在上學(xué)時(shí)就被灌輸了面向?qū)ο蟮墓逃兴枷耄吘姑嫦驅(qū)ο髲纳鲜兰o(jì)90年代到現(xiàn)在,經(jīng)久不衰,自由它的優(yōu)勢(shì)。但是在JavaScript中,如果你并不善于面向?qū)ο蟮某橄笏季S,何不嘗試一下Mixins呢?而且Mixins與類(lèi)繼承相比,還能更好的解耦合,可以用于任何Object之上,正好用上了JavaScript若類(lèi)型的優(yōu)勢(shì)。
最近在讀《Beautiful JavaScript》這本書(shū),有一些好的內(nèi)容,正好可以跟大家分享,但并不是全部,有興趣的同學(xué)也可以自己讀一下,請(qǐng)支持正版。
原文鏈接:http://t.cn/RteECIF
微信號(hào):程序員晉級(jí)之路『code-learning』
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/80185.html
摘要:月日,谷歌正式發(fā)布了的。到底能不能成為跨平臺(tái)開(kāi)發(fā)終極之選是基于前端誕生的,但是對(duì)前端開(kāi)發(fā)來(lái)說(shuō),的環(huán)境配置很麻煩,需要原生的平臺(tái)知識(shí),還要擔(dān)心遇上網(wǎng)絡(luò)問(wèn)題。現(xiàn)在已經(jīng)不是曾經(jīng)的小眾框架,這兩年里它已經(jīng)逐步成長(zhǎng)為主流的跨平臺(tái)開(kāi)發(fā)框架之一。 ...
摘要:混合中的鉤子函數(shù)同名鉤子函數(shù)都會(huì)執(zhí)行如果組件中存在鉤子函數(shù),混合中也存在相同的鉤子函數(shù),那么兩個(gè)鉤子函數(shù)都會(huì)執(zhí)行。最終的執(zhí)行結(jié)果多個(gè)混合的鉤子函數(shù)多個(gè)混合的鉤子函數(shù),會(huì)根據(jù)混合使用的順序來(lái)執(zhí)行。 1.認(rèn)識(shí)混合 混合(mixins)是一種分發(fā)Vue組件中可復(fù)用功能的非常靈活的方式 混合的作用:抽取多個(gè)組件的共同部分,增強(qiáng)組件的可復(fù)用性 混合的實(shí)質(zhì):混合對(duì)象類(lèi)似一個(gè)Vue實(shí)例,可以包含V...
摘要:的語(yǔ)言的動(dòng)態(tài)性意味著我們可以使用以上種數(shù)據(jù)類(lèi)型表示變換過(guò)渡動(dòng)畫(huà)實(shí)現(xiàn)案例前端掘金以下所有效果的實(shí)現(xiàn)方式均為個(gè)人見(jiàn)解,如有不對(duì)的地方還請(qǐng)一一指出。 讀 zepto 源碼之工具函數(shù) - 掘金Zepto 提供了豐富的工具函數(shù),下面來(lái)一一解讀。 源碼版本 本文閱讀的源碼為 zepto1.2.0 $.extend $.extend 方法可以用來(lái)擴(kuò)展目標(biāo)對(duì)象的屬性。目標(biāo)對(duì)象的同名屬性會(huì)被源對(duì)象的屬性...
摘要:本文最早為雙十一而作,原標(biāo)題雙大前端工程師讀書(shū)清單,以付費(fèi)的形式發(fā)布在上。發(fā)布完本次預(yù)告后,捕捉到了一個(gè)友善的吐槽讀書(shū)清單也要收費(fèi)。這本書(shū)便從的異步編程講起,幫助我們?cè)O(shè)計(jì)快速響應(yīng)的網(wǎng)絡(luò)應(yīng)用,而非簡(jiǎn)單的頁(yè)面。 本文最早為雙十一而作,原標(biāo)題雙 11 大前端工程師讀書(shū)清單,以付費(fèi)的形式發(fā)布在 GitChat 上。發(fā)布之后在讀者圈群聊中和讀者進(jìn)行了深入的交流,現(xiàn)免費(fèi)分享到這里,不足之處歡迎指教...
摘要:本文最早為雙十一而作,原標(biāo)題雙大前端工程師讀書(shū)清單,以付費(fèi)的形式發(fā)布在上。發(fā)布完本次預(yù)告后,捕捉到了一個(gè)友善的吐槽讀書(shū)清單也要收費(fèi)。這本書(shū)便從的異步編程講起,幫助我們?cè)O(shè)計(jì)快速響應(yīng)的網(wǎng)絡(luò)應(yīng)用,而非簡(jiǎn)單的頁(yè)面。 本文最早為雙十一而作,原標(biāo)題雙 11 大前端工程師讀書(shū)清單,以付費(fèi)的形式發(fā)布在 GitChat 上。發(fā)布之后在讀者圈群聊中和讀者進(jìn)行了深入的交流,現(xiàn)免費(fèi)分享到這里,不足之處歡迎指教...
閱讀 1439·2019-08-29 17:14
閱讀 1646·2019-08-29 12:12
閱讀 727·2019-08-29 11:33
閱讀 3261·2019-08-28 18:27
閱讀 1442·2019-08-26 10:19
閱讀 904·2019-08-23 18:18
閱讀 3525·2019-08-23 16:15
閱讀 2539·2019-08-23 14:14