函數聲明與函數表達式


定義函數的方式有2種:
  1. 函數聲明
  2. 函數表達式
函數聲明的形式
function functionName(arg1,arg2){}

  

關於函數聲明,它有一個重要的特性就是函數聲明提升,意思是在執行代碼之前會先讀取函數聲明。 這就意味着可以把函數聲明放在調用它的語句后面。
<script>
sayHi();
function sayHi(){
alert("hi,world")
}
console.log(sayHi.name) //輸出sayHi,這是sayHi(){} 的name
</script>

  

這個例子不會拋出錯誤,因為在代碼執行之前會讀取函數聲明。 第二種創建函數的方式是使用函數表達式。 最常見的創建方式:
var functionName = function(arg1,arg2){}

  

這種形式看起來好像是常規的變量賦值語句,即創建一個函數並將它賦值給變量functionName 。這種情況下創建的函數是匿名函數,因為function 關鍵字后面沒有標識符。 匿名函數的name屬性是空字符串。這也是可以理解的,畢竟是匿名函數嘛。
<script>

sayBye();
var sayBye = function(){
alert("byebye");
}
</script>
報錯:sayBye is not a function

  

理解函數提升的關鍵,就是理解函數聲明與函數表達式之間的區別。
<script>

var flag;
if(flag){
function sayHi(){
alert('hi');
}
}else{
function sayHi(){
alert('love');
}
};
sayHi(); //彈出 love
</script>

  

表面上看flag的布爾值true就是用一個sayHi()定義,否則就是用另一個定義。 實際上這在ECMAScript中屬於無效語法,javascript引擎會嘗試修正錯誤,將其轉換為合理的狀態。 但是瀏覽器嘗試修正錯誤的做法並不一致。大多數瀏覽器會返回第二個聲明,忽略condition,但chrome,火狐,opera,會在flag為true時,返回以一個函數聲明;因此使用這種方法很危險,不應該出現在你的代碼中。不過,如果是使用函數表達式就沒有什么問題了。
<script>
var sayBye;
var flag;
if(flag){
sayBye = function(){
alert("bye");
}
}else{
sayBye = function(){
alert("bye lizi");
}
};
sayBye(); //彈出 bye lizi
</script>
也可以這樣寫:
<script>

function mult(num){
if(num<=0){
return num = 1;
}else{
return num * arguments.callee(num-1);
}
};



alert(mult(3)) ;
</script>

  

arguments.callee指向一個正在執行的函數的指針,因此可以用它來實現對函數的遞歸調用 通過使用arguments.callee代替函數名,可以確保無論怎樣調用函數都不會出問題。因此,在編寫地櫃函數時,使用arguments.callee總比使用函數名更保險。 但在嚴格模式下,不能通過腳本方位arguemnts.callee,訪問這個屬性會導致錯誤
<script>
'use strict';
function mult(num){
if(num<=0){
return num = 1;
}else{
return num * arguments.callee(num-1);
}
};
alert(mult(3)) ; //'caller', 'callee', and 'arguments' properties may not be accessed on strict mode //functions
</script>

  

不過,可以使用命名函數表達式來達成相同的結果。
<script>
var interation = (function f(num){
if(num <=1){
return num = 1;
}else{
return num * f(num-1);
}
})

alert(interation(3));
</script>

  

以上代碼創建了一個名為f()的命名函數表達式,然后將它賦值給變量interation.即使把函數賦值給了另一個變量,函數的名字f仍然有效,所以遞歸調用照樣能正常完成。這種方式在嚴格模式和非嚴格模式下都行得通。

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com