函數(shù)型 VS 面向?qū)ο笮偷膉avascript程序設(shè)計_第1頁
函數(shù)型 VS 面向?qū)ο笮偷膉avascript程序設(shè)計_第2頁
函數(shù)型 VS 面向?qū)ο笮偷膉avascript程序設(shè)計_第3頁
函數(shù)型 VS 面向?qū)ο笮偷膉avascript程序設(shè)計_第4頁
函數(shù)型 VS 面向?qū)ο笮偷膉avascript程序設(shè)計_第5頁
已閱讀5頁,還剩4頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、靈活的js語言可以輕易的就完成截然相反的兩種編程模式函數(shù)型程序設(shè)計和面向?qū)ο蟮某绦蛟O(shè)計。js原生的支持將函數(shù)當做變量來處理。你可以將一個函數(shù)賦值給一個變量,然后把他傳給其他的變量。抽象的說,我們可以認為js的函數(shù)是一個特殊的變量:只不過他的形式是“函數(shù)”。js原生的也提供對象。在js中,對象可以認為是一系列平面化的屬性值和方法。他們看起來像是一個數(shù)據(jù)字典,而不像你在其他諸如java、c+、c#中看到的對象那樣。在經(jīng)典的面向?qū)ο缶幊讨?,類表示可以通過new操作符來生成一個實例的模板。但是在js中,沒有可以當做藍本來生成對象的。在js中,一個對象的藍本更像是一個數(shù)據(jù)字典。所以在js中,你可以創(chuàng)建對

2、象,然后可以在對象中存儲數(shù)據(jù)。當然,js的對象也提供一定程度的面向?qū)ο蟮奶匦?,比如封裝和繼承。js開發(fā)越來越熱,兩種模式的優(yōu)劣是什么?js對兩種模式都支持,但是問題的答案得你自己來弄清楚。它兩種都支持,但并不是某一種特別的合適。OOP的js框架和函數(shù)型的js都同時存在。函數(shù)型程序設(shè)計簡介函數(shù)型程序設(shè)計中,每個代碼段都是在”function”之上建立的,這與傳統(tǒng)的OOP建立在”class”之上是不同的。一個函數(shù)只是對輸入的展現(xiàn)的一種操作。一個函數(shù)只是接收一些輸入,然后返回一些輸出,其他的都是隱藏起來的。在函數(shù)型程序設(shè)計中,你通過在一個函數(shù)中調(diào)用其他的函數(shù)來完成程序的輸入與輸出。這通常都沒有可以處

3、理輸入、存儲數(shù)據(jù)以及一系列的狀態(tài)更新的那一層。函數(shù)就像一個數(shù)值一樣,可以作為參數(shù)傳遞給其他函數(shù)。javascript與函數(shù)型程序設(shè)計需要明確的一個事實是:js并不是像F#那樣真正的函數(shù)型程序設(shè)計語言,雖然他有一些函數(shù)型程序設(shè)計模式的特性。利用這些特性,你也可以用js做很好的工作。到今天為止,使用jQuery就是這種模式最廣泛的應(yīng)用了。匿名函數(shù)是函數(shù)型程序設(shè)計的精華之所在。匿名函數(shù)是lambda計算式的另一種形式,一種可以適配經(jīng)流行的編碼風(fēng)格。123function (x,yreturn x + y;普通函數(shù)和匿名的函數(shù)的唯一區(qū)別就在于名字。在函數(shù)的上下文中,當你只是需要函數(shù)的返回值作為參數(shù)來使

4、用的時候,并不是非得要給他一個函數(shù)名。通過下面這個例子我們來看看:123456789101112131415161718/ 一個用來計算和的函數(shù)var CalcTotal = function(x, y return x + y;/ 增加稅率var AddTaxes = function(x return x * 1.2;/ 最終的計算函數(shù)var CalcTotalPlusTaxes = function (fnCalcTotal, fnAddTaxes, x, y return fnAddTaxes(fnCalcTotal(x, y;/ 執(zhí)行var result = CalcTotalPlu

5、sTaxes(CalcTotal, AddTaxes, 40, 60;alert(result;需要注意的是,你也可以使用匿名函數(shù),而不是非得通過一個中間變量來傳遞給最終的計算式。123alert(function(xreturn x * 1.2(100;將匿名函數(shù)看做一個變量,可以很輕松的將數(shù)據(jù)和特性合并在一起。這也給你了一個機會去試驗一些其他的設(shè)計原則。當高一級的模塊(無論對象還是函數(shù))需要低一級的模塊提供的返回值的時候,就可以將低一級的模塊直接當做參數(shù)傳過去。很多情況下,這會提高函數(shù)參數(shù)的可讀性,并且讓代碼更優(yōu)雅一些,當然,也會讓你在處理復(fù)雜事物的時候更加得心應(yīng)手。jQuery和函數(shù)型程

6、序設(shè)計jQuery在函數(shù)型程序設(shè)計方面吸引了人們極大的關(guān)注。整個jQuery庫都是基于jquery對象或者說$。$是DOM元素的一個封裝,DOM元素也可以通過$(表達式傳遞進去。另外,jQuery支持鏈式操作,每一個函數(shù)運行之后都會返回同一個jquery對象。jQuery非常高效,因為你可以在主要工作是操作DOM元素的WEB編程環(huán)境下最大限度的發(fā)揮出函數(shù)型程序設(shè)計的威力。你也許是jQuery的粉絲,并且覺得這種函數(shù)式的操作非常贊。但是,這不是需要完全把這種編程模式到處使用的理由。我們通過下面這個jQuery源碼來看個例子:12345678jQuery.fn = jQtotype

7、 = init: function( selector, context . ,size: function( return this.length; ,each: function( callback, args return jQuery.each( this, callback, args ; ,ready: function( fn . :可以看到,jQuery對象有他自己的原型,也有一些自有的方法:比如size和each。更有意思的是,當你寫jQuery的插件的時候,你只是給通過添加一個函數(shù)擴展了原型方法。至此,所有高效的js編程,都是兩種模式混合的結(jié)果。當然jQuery中函數(shù)型的模

8、式更加明顯一些。javascript中的對象真正面向?qū)ο缶幊讨械膶ο笈cjavascript中的對象有一個很明顯的不同。在面向?qū)ο蟮恼Z言中,類是你要使用的對象的藍本。在javascript中,你所使用的對象的藍本是一個數(shù)據(jù)字典或者一個函數(shù)。當你在js中創(chuàng)建了一個對象,你就擁有一個你可以填進去任何數(shù)據(jù)的空的數(shù)據(jù)字典。之前說過,通過一些方法,你可以創(chuàng)建一些自定義的對象或者繼承自現(xiàn)有的對象。這只在js中有效。當你需要通過添加中間的轉(zhuǎn)化來接近真正的面向?qū)ο笳Z言的時候,在js中有兩種辦法:閉包和原型。在講述那兩種辦法之前,我們先來講講js中的對象類型和他的用法。你可以通過new關(guān)鍵字來創(chuàng)建一個空的對象,然

9、后你可以給這個對象添加進去你想要的內(nèi)容:123456789101112131415161718var person = new Object(;person.Name = Dino;person.LastName = Esposito;person.BirthDate = new Date(1979,10,17person.getAge = function( var today = new Date(;var thisDay = today.getDate(;var thisMonth = today.getMonth(;var thisYear = today.getFullYear(;v

10、ar age = thisYear-this.BirthDate.getFullYear(-1;if (thisMonth this.BirthDate.getMonth(age = age +1;elseif (thisMonth = this.BirthDate.getMonth( &thisDay = this.BirthDate.getDate(age = age +1;return age;我們現(xiàn)在擁有一個名為person的對象,但是沒有Person對象。在js中,所有的原聲對象都有一個只讀的prototype屬性。通過這個屬性,你可以用來提供一些函數(shù),這些函數(shù)在使用new關(guān)鍵字的時

11、候,新生成的對象可以與原對象共享這些方法。下面有兩種方法可以在js中實現(xiàn)面向?qū)ο缶幊獭Mㄟ^閉包實現(xiàn)面向?qū)ο箝]包是編程語言中的一個基本概念。在js中,閉包是指那些擁有同樣上下文的變量和方法的一個函數(shù)。下面這個例子就是使用閉包來模擬一個Person類:1234567891011121314151617181920var Person = function(name, lastname, birthdatethis.Name = name;this.LastName = lastname;this.BirthDate = birthdate;this.getAge = function( var t

12、oday = new Date(;var thisDay = today.getDate(;var thisMonth = today.getMonth(;var thisYear = today.getFullYear(;var age = thisYear-this.BirthDate.getFullYear(-1;if (thisMonth this.BirthDate.getMonth(age = age +1;elseif (thisMonth = this.BirthDate.getMonth( &thisDay = this.BirthDate.getDate(age = age

13、 +1;return age;可以看出,閉包就是父類的構(gòu)造函數(shù)。在閉包模式中,構(gòu)造器包含類成員的聲明,并且這些成員都是封裝起來的。另外,成員都是基于實例的,所以會消耗內(nèi)存。如何使用呢:12var p = new Person(Rock,ux,new Date(;alert( + is + p.getAge(;閉包模式是完全封裝的,僅此而已。原型模式的面向?qū)ο蠓椒ㄍㄟ^js中prototype對象,你可以定義一個類的結(jié)構(gòu)。下面這個例子用來說明怎樣避免使用閉包來重寫Person類。12345678910111213141516171819202122232425262728/ 構(gòu)造器va

14、r Person = function(name, lastname, birthdatethis.initialize(name, lastname, birthdate;/ 成員Ptotype.initialize(name, lastname, birthdatethis.Name = name;this.LastName = lastname;this.BirthDate = birthdate;Ptotype.getAge = function(var today = new Date(;var thisDay = today.getDate(;v

15、ar thisMonth = today.getMonth(;var thisYear = today.getFullYear(;var age = thisYear-this.BirthDate.getFullYear(-1;if (thisMonth this.BirthDate.getMonth(age = age +1;elseif (thisMonth = this.BirthDate.getMonth( &thisDay = this.BirthDate.getDate(age = age +1;return age;在原型模式下面,構(gòu)造器和成員之間結(jié)構(gòu)清晰,但是構(gòu)造函數(shù)是必須的。

16、這里并沒有私有成員,var關(guān)鍵字可以讓其只在閉包中有效。你可以通過定義setter/getter來操作你需要的屬性,但是這些屬性在類外面也是可以直接訪問修改的。你可以通過一些特殊的操作(比如添加前綴)來定義私有變量。只是一種辦法而已。原型模式可以很簡單的實現(xiàn)繼承:12345Developer = function Developer(name, lastname, birthdatethis.initialize(name, lastname, birthdate;Dtotype = new Person(;需要注意的是,你必須通過使用this關(guān)鍵字來訪問原型中的相關(guān)成

17、員方法。閉包還是原型?在原型模式中,所有的成員都是共享的。所以,相比而言,內(nèi)存的開銷要小一些。除去語法方面的不同,通過原型模式定義的類更加接近經(jīng)典意義上的面向?qū)ο笳Z言。閉包還是原型的選擇還要從性能和瀏覽器的兼容性來考慮。原型模式的加載速度不錯,而且在Firefox中性能也很好。(相比而言,閉包模式在IE下面的加載更快一些。)原型模式對于智能感知支持不錯,這樣在一些IDE中(比如VS)就能得到很好的工具支持。原型模式下,你不必通過創(chuàng)建一個實例來查看類型信息,閉包模式下就不行。最后,調(diào)試的時候,原型模式可以方便的訪問私有成員,閉包模式下面得多幾步操作才行。舉個例子,微軟的ajax庫使用的就是原型模式(閉包模式從未被考慮)。結(jié)論Javascript并不是純粹的函數(shù)型或者面向?qū)ο蟮恼Z言。但是他從兩種語言都有借鑒,所以你需要做好一些準備。如今,Javascript對于編寫客戶端的網(wǎng)頁和移動應(yīng)用程序來說必不可少。而且現(xiàn)在的腳本編寫也不像當初

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論