JavaScript權威指南學習之第8章 函數

1、一條函數聲明語句實際上聲明瞭一個變量,並把一個函數對象賦值給它。

2、函數聲明語句並非真正的語句,ECMAScript規範只是允許它們作爲頂級語句。它們可以出現在全局代碼裏,或者內嵌在其他函數中,但它們不能出現在循環、條件判斷,或者try/cache/finally以及with語句中。注意,此限制僅適用於以語句聲明形式定義的函數。函數定義表達式可以出現在JavaScript代碼的任何地方。

3、根據ECMAScript 3和非嚴格的ECMAScript5對函數調用的規定,調用上下文(this的值)是全局對象。然而,在嚴格模式下,調用上下文則是undefined。以函數形式調用的函數通常不使用this關鍵字。不過,“this”可以用來判斷當前是否是嚴格模式。

//定義並調用一個函數來確定當前腳本運行時是否爲嚴格模式

var strict = (function(){ return !this; }());

4、JavaScript,JScript,ECMAScript及對應瀏覽器的版本:

JavaScript

JScript

ECMAScript

Release date

Netscape Navigator

Firefox

IE

Opera

Safari

Chrome

1.0

1.0

 

March 1996

2.0

 

3.0- early versions, August 1996

 

 

 

1.1

2.0

 

August 1996

3.0

 

3.0- later versions, January 1997

 

 

 

1.2

 

 

June 1997

4.0-4.05

 

 

 

 

 

1.3

3.0

ECMA-262 1st edition/

ECMA-262 2nd edition

October 1998

4.06-4.7x

 

4.0 -Oct 1997

 

 

 

1.4

4.0

 

 

Netscape Server

 

 

 

 

 

 

5.0

 

March 1999

 

 

5.0

 

 

 

 

5.1

 

 

 

 

5.01

 

 

 

1.5

5.5

ECMA-262 3rd edition

November 2000

6.0

1.0

5.5-July 2000

6.0-11.0

3.0-5

1.0-10.0.666

 

5.6

ECMA-262 3rd edition

October 2001

 

 

6.0

 

 

 

 

5.7

ECMA-262 3rd edition + ECMA-327 (ES-CP)

November 2006

 

 

7

 

 

 

 

5.8

ECMA-262 3rd edition + ECMA-327 (ES-CP) + JSON (RFC 4627)

March 2009

 

 

8

 

 

 

1.6

 

1.5 + Array extras

+ Array and String generics + E4X

 

November 2005

 

1.5 (Gecko 1.8)

 

 

 

 

1.7

 

1.6 + Pythonic generators

+ Iterators + let

 

October 2006

 

2.0(Gecko 1.8.1)

 

 

 

 

1.8

 

1.7 + Generator expressions

+ Expression closures

June 2008

 

3.0(Gecko 1.9)

 

 

 

 

1.8.1

 

1.8 + Native JSON support

+ Minor Updates

 

 

3.5

 

 

 

 

1.8.2

 

1.8.1 + Minor updates

June 22, 2009

 

3.6

 

 

 

 

1.8.5

 

1.8.1 + ECMAScript 5 Compliance

July 27, 2010

 

4

9

 

 

 

2.0 (work in progress)

 

Harmony(work in progress)

 

 

 

 

 

 

 

 

5、構造函數通常不使用return關鍵字,它們通常初始化新對象,當構造函數的函數體執行完畢時,它會顯式返回。在這種情況下,構造函數調用表達式的計算結果就是這個新對象的值。然而如果構造函數顯式地使用return有返回一個對象,那麼調用表達式的值就是這個對象。如果構造函數使用return語句但沒有指定返回值,或者返回一個原始值,那麼這時將忽略返回值,同時使用這個新對象作爲調用結果。

6、可以接收任意個數的實參的函數稱爲“不定實參函數”(varargs function)。注意,不定實參函數的實參個數不能爲零,arguments[]對象最適合的應用場景是在這樣一類函數中,這類函數包含固定個數的命名和必需參數,以及隨後個數不定的可選實參。

7、除了數組元素,實參對象還定義了callee和caller屬性。在ECMAScript5嚴格模式中,對這兩個屬性的讀寫操作都會產生一個類型錯誤。而在非嚴格模式下,ECMAScript標準規範規定callee屬性指代當前正在執行的函數。caller是非標準的,但大多數瀏覽器都實現了這個屬性,它指代調用當前正在執行的函數的函數。通過caller屬性可以訪問調用棧。Callee屬性在某些時候會非常有用,比如在匿名函數中通過callee來遞歸地調用自身。

var factorial = function(x){

         if( x <= 1) return1;

         return x *arguments.callee(x-1);

}

8、在函數中聲明的變量在整個函數體內都是可見的(包括在嵌套的函數中),在函數的外部是不可見的。不在任何函數內聲明的變量是全局變量,在整個JavaScript程序中都是可見的。在JavaScript中是無法聲明只在一個代碼塊內可見的變量的,基於這個原因,我們常常簡單地定義一個函數用做臨時的命名空間,在這個命名空間內定義的變量都不會污染到全局命名空間。

function mymodule(){

         //模塊代碼

         //這個模塊所使用的所有變量都是局部變量

         //而不會污染全局命名空間

}

mymodule() //不要忘了還要調用這個函數

這段代碼僅僅定義了一個單獨的全局變量:名叫“mymodule”的函數。這樣還是太麻煩,可以直接定義一個匿名函數,並在單個表達式中調用它:

(function(){           //mymodule()函數重寫爲匿名的函數表達式

         //模塊代碼

}());                  //結束函數定義並立即調用它

Function之前的左圓括號是必需的,因爲如果不寫這個左圓括號,JavaScript解釋器會試圖將關鍵字function解析爲函數聲明語句。使用圓括號JavaScript解釋器纔會正確地將其解析爲函數定義表達式。

9、閉包是指函數變量可以被隱藏於作用域鏈之內,因此看起來是函數將變量“包裹”了起來。

10、函數定義時的作用域鏈到函數執行時依然有效。每次調用JavaScript函數的時候,都會爲之創建一個新的對象用來保存局部變量,把這個對象添加至作用域鏈中。當函數返回的時候,就從作用域鏈中將這個綁定變量的對象刪除。如果不存在嵌套的函數,也沒有其他引用指向這個綁定對象,它就會被當作垃圾回收掉。如果定義了嵌套的函數,每個嵌套的函數都各自對應一個作用域鏈,並且這個作用域鏈指向一個變量綁定對象。但如果這些嵌套的函數對象在外部函數中保存下來,那麼它們也會和所指向的變量綁定對象一樣當作垃圾回收。但是如果這個函數定義了嵌套的函數,並將它作爲返回值返回或者存儲在某處的屬性裏,這時就會有一個外部引用指向這個嵌套的函數。它就不會被當作垃圾回收,並且它所指向的變量綁定對象也不會被當作垃圾回收。如果使用不慎,閉包很容易造成“循環引用”,當DOM對象和JavaScript對象之間存在循環引用時需要格外小心,在某些瀏覽器下會造成內存泄漏。

11、關於Function()構造函數有幾點需要特別注意:

l  Function()構造函數允許JavaScript在運行時動態地創建並編譯函數。

l  每次調用Function()構造函數都會解析函數體,並創建新的函數對象。如果是在一個循環或者多次調用的函數中執行這個構造函數,執行效率會受影響。相比之下,循環中的嵌套函數和函數定義表達式則不會每次執行時都重新編譯。

l  最後一點,也是關於Function()構造函數非常重要的一點,就是它所創建的函數並不是使用詞法作用域,相反,函數體代碼的編譯總是會在頂層函數(也就是全局作用域)執行。

12、不完全函數是一種函數變換技巧,即把一次完整的函數調用拆成毒刺函數調用,每次傳入的實參都是完整實參的一部分,每個拆分開的函數叫做不完全函數(partial function),每次函數調用叫做不完全調用(partial application),這種函數變換的特定是每次調用都返回一個函數,直到得到最終運行結果爲止,舉一個簡單的例子,將對函數f(1,2,3,4,5,6)的調用修改爲等價的f(1,2)(3,4)(5,6),後者包含三次調用,和每次調用相關的函數就是“不完全函數”。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章