JavaScript函數表達式
一、序
定義函數的方式有兩種:一種是函數聲明,另一種就是函數表達式;
1.1 函數聲明
function functionName(arg){ //函數體}關于函數聲明,它有一個重要特征就是函數聲明提升,意思就是在執行代碼之前會先讀取函數聲明。這就意味著可以把函數放在調用它的語句后面。如下所示:
helloworld(); //在代碼執行之前會先讀取函數聲明function helloworld(){ console.log("hello world");}1.2 函數表達式
var functionName=function(arg){ //函數體}這種形式看起來好像是常規的變量賦值語句,即創建一個函數并將它賦值給變量functionName。這種情況下創建的函數叫做匿名函數。因為function關鍵字后面沒有標識符。
函數表達式與其他表達式一樣,在使用之前必須先賦值;如下面代碼就會導致錯誤;
helloworld(); //錯誤,還未賦值,函數不存在var helloworld=function(){ console.log("hello world");}有了函數表達式,我們就可以動態給函數表達式賦值了;如下面代碼:
var helloworld; //聲明if(condition){ //條件 helloworld=function(){ //賦值 console.log("hello world"); }}else{ helloworld=function(){ //賦值 console.log("你好,世界"); }}二、遞歸函數
遞歸函數是在一個函數通過名字調用自身的情況下構成的(和C#等語言一樣,所以程序的核心思想是差不多,只是在語法上有些差異,學好一門語言的基礎,學習其他就會輕松很多),舉個經典的遞歸面試題,一列數的規則如下 : 1 、 1 、 2 、 3 、 5 、 8 、 13 、 21 、 34…… 求第 30 位數是多少, 用遞歸算法實現,代碼如下所示:
function foo(n) { if (n <= 0) return 0; else if (n > 0 && n <= 2) return 1; else return foo(n - 1) + foo(n - 2); }雖然這個函數表明看來沒有什么問題,但下面的代碼卻可能導致它出錯:
var foo1 = foo; foo = null; console.log(foo1(34));
以上代碼先把foo()函數保存在變量foo1中,然后將foo變量設為null,結果指向原始函數的引用只剩下一個。但在接下來調用foo1()時,由于必須執行foo(),而foo已經為null了,所以就會導致錯誤;在這種情況下,使用arguments.callee可以解決這個問題。arguments.callee是一個指向正在執行的函數的指針,因此可以用它來實現對函數的遞歸調用
新聞熱點
疑難解答
圖片精選