一起來啃《JavaScript語言精粹》----函式
一、呼叫
方法呼叫模式
當一個函式被儲存為物件的一個屬性時,我們稱它為一個方法。如果呼叫表示式包含一個提取屬性的動作,那麼它就是被當做一個方法來呼叫。
Paste_Image.png
方法可以使用this訪問自己所屬的物件,透過this可取得它們所屬物件的上下文的方法稱為公共方法。
-
函式呼叫模式
當一個函式並非一個物件的屬性時,那麼它就是被當做一個函式來呼叫:
var sum = add(3, 4);//7
以此模式呼叫函式時,this被繫結到全域性物件。Paste_Image.png
這事語言設計的一個錯誤,錯誤後果就是方法不能利用內部函式來幫助它工作,因為內部函式的this被繫結了錯誤的值,所以不能共享該方法對物件的訪問權。
解決方案:
為該方法定義一個變數並給它賦值為this,那麼內部函式就可以透過那個變數訪問到this:Paste_Image.png
構造器呼叫模式
如果在一個函式前面帶上 new 來呼叫,那麼背地裡將會建立一個連線到該函式的prototype成員的新物件,同時 this 會被繫結到那個新物件上。
//建立一個名為Quo的構造器函式。它構造一個帶有status屬性的物件。
var Quo = function(string){
this.status = string
}
//給Quo的所有例項提供一個名為get_status的公共方法。
Quo.prototype.get_status = function(){
return this.status;
};
//構造一個Quo例項。
var myQuo = new Quo('confused');
myQuo.get_status()//'confused'Apply呼叫模式
apply方法讓我們構建一個引數陣列傳遞給呼叫函式。它也允許我們選擇this的值。apply方法接收兩個引數,第一個是要繫結給this的值,第二個就是一個引數陣列。
Paste_Image.png
二、擴充型別的功能
-
我們可以透過給Function.prototype 增加方法來使得該方法對所有函式可用
Paste_Image.png
透過給Function.prototype 增加一個method方法,我們下次給物件增加方法的時候就不必鍵入prototype這幾個字元,省掉了一點麻煩。
-
JavaScript沒有專門的整數型別,但有時候確實只需要提取數字中的整數部分。JavaScript本身提供的取整方法有些醜陋。我們可以透過Number.prototype增加一個integer方法來改善它。它會根據數字的正負來判斷是使用Math.ceiling還是Math.floor。
Paste_Image.png
PS:這裡需要指出的是Javascript的原型繼承機制,可以形象的理解為Object是祖師爺爺,Function既當爹又當媽,剩下的Number,String,Array等都是兒女:
Number,String,Array => Function => Object
Paste_Image.png
另外,基本型別的原型是公用結構,所以在類庫混用時務必小心。一個保險的做法是隻在確定沒有該方法時才新增它。
//符合條件時才增加方法。
Function.prototype.method = function(name,func){
if(!this.prototype[name]){
this.prototype[name] = func;
}
return this;
}
三、閉包
-
我們透過呼叫一個函式的形式去初始化myObject,該函式會返回一個物件字面量。函式里定義一個value變數。該變數對increment和getValue方法總是可用的,但是函式的作用域使得它對其他的程式來說是不可見的。
Paste_Image.png
這個例子我們並沒有把一個函式賦值給myObject。我們是把呼叫該函式後返回的結果賦值給它。
Paste_Image.png
當我們呼叫quo時,它返回包含get_status方法的一個新物件。該物件的一個引用儲存在myQuo中。即使quo已經返回了,但get_status方法仍然享有訪問quo物件的status屬性的特權。get_status方法並不是訪問該引數的一個副本,它訪問的就是該引數本身。這是可能的,因為該函式可以訪問它被建立時所處的上下文環境,這被稱為閉包。
-
來看一個更有用的例子
Paste_Image.png
1.我們呼叫fade,把document.body作為引數傳遞給它,fade函式設定level為1.它定義一個step函式,接著呼叫setTimeout,並傳遞step函式和一個時間(100毫秒)給它。然後它返回,fade函式結束。
2.在大約100毫秒後,step函式被呼叫。它把fade函式的level變數轉換為16位字元。接著,它修改fade函式得到的節點的背景顏色。然後檢視fade函式的level變數。如果背景色尚未變成白色,那麼它增大fade函式的level變數,接著用setTimeout預定讓它自己再次執行。
3.step函式很快再次被呼叫。但這次,fade函式的level變數值變成2.fade函式在之前已經返回了,但只要fade的內部函式需要,它的變數就會持續保留。 從一個經典的錯誤說起
構造六個div,當點選一個div時,按照預期,應該打出相應div的值,但是它總是會顯示div的數量。因為事件處理器函式繫結了變數i本身,而不是函式在構造時的變數i的值,i始終無法被釋放。
Paste_Image.png
避免在迴圈中建立函式,它可能只會帶來無謂的計算,還會引起混淆,正如上面那個經典的錯誤。我們可以先在迴圈外建立一個輔助函式,讓這個輔助函式再返回一個繫結了當前i值的函式,這樣就不會導致混淆了。改良後的例子,用正確的方式給一個陣列中的節點設定事件處理程式
Paste_Image.png
另一種解決辦法,這裡我們用一個立即執行函式給它包住,我們不再依賴i,而是用另外一個變數n把它保留下來。
Paste_Image.png
四、記憶
-
函式可以將先前操作的結果記錄在某個物件裡,從而避免無謂的重複運算。這種最佳化被稱為記憶。JavaScript的物件和陣列要實現這種最佳化是非常方便的。
比如說,我們想要一個遞迴函式來計算Fibonacci數列。一個Fibonacci數列是之前兩個Fibonacci數字之和。最前面的兩個數字是0和1。Paste_Image.png
但是這樣做了很多無謂的工作。fibonacci函式被呼叫了453次。如果我們讓該函式具備記憶功能,就能顯著地減少運算量。
我們在一個名為memo的陣列裡儲存我們的儲存結果,儲存結果可以隱藏在閉包中。當函式被呼叫時,這個函式首先檢查結果是不是已經存在,如果存在,就立即返回這個結果。Paste_Image.png
這個函式返回的結果相同,但是它只被呼叫了29次。 -
我們可以編寫一個函式來幫助我們構造帶記憶功能的函式。memoizer函式取得一個初始的memo陣列和formula函式。它返回一個管理meno儲存和在需要時呼叫formula函式的recur函式。我們把這個recur函式和它的引數傳遞給formula函式:
Paste_Image.png
現在,我們可以使用memoizer函式來定義fibonacci函式,提供其初始的memo陣列和formula函式:
Paste_Image.png
透過設計這種產生另一個函式的函式,極大地減少了我們的工作量。例如,要產生一個可以記憶的階乘函式,我們只需提供基本的階乘公式即可:Paste_Image.png
作者:韓寶億
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2310/viewspace-2812276/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 《JavaScript語言精粹》學習筆記二JavaScript筆記
- 《JavaScript語言精粹》學習筆記一JavaScript筆記
- 試讀《JavaScript語言精粹(修訂版)》JavaScript
- 《JavaScript語言精粹(修訂版)》試讀JavaScript
- 函式式JavaScript(2):如何打造“函式式”程式語言?函式JavaScript
- 瞭解 JavaScript 函數語言程式設計 - 宣告式函式JavaScript函數程式設計函式
- 使用函式式語言來建立領域模型函式模型
- C語言函式手冊:c語言庫函式大全|C語言標準函式庫|c語言常用函式查詢C語言函式
- 一起來學習 Python 函數語言程式設計Python函數程式設計
- Go 語言函式Go函式
- C語言函式一本道來C語言函式
- JavaScript 函式語法JavaScript函式
- JavaScript函數語言程式設計(純函式、柯里化以及組合函式)JavaScript函數程式設計函式
- JavaScript函數語言程式設計,真香之組合函式(二)JavaScript函數程式設計函式
- JavaScript函數語言程式設計之深入理解純函式JavaScript函數程式設計函式
- C語言 itoa函式及atoi函式C語言函式
- C語言 execve()函式C語言函式
- R語言函式-tolowerR語言函式
- C語言常用函式C語言函式
- GO語言————6.1 函式Go函式
- q語言的函式函式
- C語言的函式C語言函式
- Go 語言 -make函式Go函式
- 瞭解 JavaScript 函數語言程式設計 -- 什麼是純函式JavaScript函數程式設計函式
- 為什麼純函式式語言至今無法流行起來?函式
- javascript函數語言程式設計JavaScript函數程式設計
- JavaScript 函數語言程式設計JavaScript函數程式設計
- C語言函式呼叫棧C語言函式
- SQL語言基礎(函式)SQL函式
- go語言學習-函式Go函式
- 詳解C語言函式C語言函式
- tmpnam() - C語言庫函式C語言函式
- tmpfile() - C語言庫函式C語言函式
- R語言的scale函式R語言函式
- C語言時間函式C語言函式
- c語言函式庫(轉)C語言函式
- C語言 函式指標C語言函式指標
- 08. C語言函式C語言函式