標籤:
第八章函數
函數是JavaScript中很重要的一個章節,懂得這個章節就可以輕鬆閱讀別人的代碼,會熟悉一些不常用的代碼寫法。
按照難易程度控制文章的長度。
前言:
函數是一段只定義一次,可能被執行或調用任意次的JavaScript代碼。
若一個函數掛載在一個對象上,作為對象的屬性,稱為對象的方法。當通過這個對象來調用函數時,該對象就是此次調用的上下文,函數會隱式自動獲得內容物件。
JavaScript中函數即對象,程式可以任意操控。
JavaScript的函數可以嵌套在其他函數中定義,這樣嵌套的函數可以訪問外層函數範圍中的任何變數。這意味著JavaScript函數構成一個閉包。
8.1函數定義
1、 函數特徵:
1. 函數名--可選 2. function 3. () 4. {}
2、函數定義方法
- 函數語句
運算式
1.函數語句就是普通的function funname(){}
備忘:使用函數時必須在函數定義之後或是提前聲明。
2.運算式就是var variable = function(){}
備忘:使用必須是變數已經聲明。
“=”右邊的函數就是一個匿名函數,創造完畢函數後,又將該函數賦給了左邊變數。
3、函數命名
| 普通函數 |
內建函式,私人函數 |
| like_this() |
_like_this() |
| likeThis(); |
|
使用簡短名稱,或是使用符號重新命名。
8.2函數調用8.2.1函數調用
若函數返回是因為解譯器到達結尾,則傳回值是undefined。
若return語句沒有值,也是返回undefined。
以函數方式調用通常不能使用this關鍵字。
strict 模式下函數中的this是undefined,非strict 模式下是全域對象
8.2.2方法調用
一個方法就是儲存在一個對象屬性中的函數。
方法和函數最大的區別就是調用上下文。函數只有全域變數和undefined兩種,方法時根據調用的對象來確定內容相關的。
this是一個關鍵字不是變數,也不是屬性名稱,不允許對this賦值。
關鍵字this沒有範圍的限制,嵌套函數不會從調用它的函數中繼承this。
若嵌套函數作為方法調用,this指向調用它的對象。若嵌套函數作為函數調用,其this值是全域對象(非strict 模式),或undefined(strict 模式下)
8.2.1和8.2.3實際上是對之前8.1提出來的兩種定義函數的方法的分別調用詳述。
8.2.3建構函式調用
顯示返回新對象
沒有形參的建構函式可以省略()
8.3 函數的實參和形參8.3.1可選的形參
對參數做檢查,如果沒有的話就使用新對象
當調用函數的時候傳入的實參比函式宣告時指定的形參個數要少時,剩下的形參都將設定為undefined值。
8.3.2可變長的實參列表:實參對象
當調用函數傳入的實參個數超過形參個數時,沒辦法直接獲得未命名的引用。在函數內,標示符arguments是指向實參對象的引用,其是一個類數組對象。
arguments 對象,傳參隨便傳多少個參數,接受的時候使用arguments對象以數組的方式獲得。
ECMA5已經移除了實參對象。
strict 模式下無法使用arguments作形參變數名或是局部變數名,也不能賦值。
非strict 模式是作為標識符
函數可以接受任意個數的實參,這種函數稱為不定實參函數,arguments[]適合實現這種情境的函數。
arguments並不是真正的數組,是一個實參對象,修改其值可以相應修改傳入的實參。
8.3.3將對象屬性用作實參
使用實參對象+索引值對的方式免去記憶參數的位置
8.3.4實參類型
在函數內部做類型檢查和處理
8.4作為值的函數
在JavaScript最頂層代碼,範圍鏈由一個全域對象組成。
在不包含嵌套函數體內,範圍上有兩個對象,第一個是定義函數參數和局部變數的對象,第二個是全域對象。
當定義一個函數時,它實際上至少儲存一個範圍鏈。
當調用這個函數時,它建立一個新的對象來儲存它的局部變數,並將這個對象添加至儲存的那個範圍鏈上,同時建立一個新的更長的範圍鏈。
當函數返回的時候,就從範圍鏈中將這個綁定的變數對象刪除。若不存在嵌套函數,也沒有其他引用指向這個綁定的對象,則會把記憶體回收。
對於嵌套函數,每次調用外部函數時,內建函式又會重新定義一遍。因為每次調用外部函數的時候,範圍都不同的。
內建函式在每次定義的時候都有微小的差別,在每次調用外部函數時,內建函式代碼相同,而關聯這段代碼的範圍鏈不相同。
嵌套函數不會將範圍內私人成員複製一份,也不會對所綁定的變數產生靜態快照。
counter(){ var n=0; return { count: function(){ return n++;}, reset: function(){ n=0;} }; } //每次調用counter都會建立一個新範圍鏈和一個新的私人變數 var >c=counter(),d=counter(); c.count(); //-->1 d.count();//-->1 d.count();//-->2
閉包實現的原理是將內部引用賦給外部變數,利用外部變數永久儲存對內部變數的引用,不會被記憶體回收機制處理掉。
JavaScript基礎學習之-JavaScript權威指南--8.1-8.4函數