一、function概述
javascript中的函數不同于其他的語言,每個函數都是作為一個對象被維護和運行的。通過函數對象的性質,可以很方便的將一個函數賦值給一個變量或者將函數作為參數傳遞。
函數對象與其他用戶所定義的對象有著本質的區別,這一類對象被稱之為內部對象。內置對象的構造器是由JavaScript本身所定義的。
二、function對象的創建
在JavaScript中,函數對象對應的類型是Function,可以通過new Function()來創建一個函數對象,也可以通過function關鍵字來創建一個對象。
//使用new Function()方式創建
var myFunction=new Function("a","b","return a+b");
//使用function關鍵字創建
function myFunction(a,b) {
return a + b;
}
用關鍵字創建對象的時候,在解釋器內部,就會自動構造一個Function對象,將函數作為一個內部的對象來存儲和運行。從這里也可以看到,一個函數對象 名稱(函數變量)和一個普通變量名稱具有同樣的規范,都可以通過變量名來引用這個變量,但是函數變量名后面可以跟上括號和參數列表來進行函數調用。
new Function()的語法規范如下:
var funcName=new Function(p1,p2,...,pn,body);
參數的類型都是字符串,p1到pn表示所創建函數的參數名稱列表,body表示所創建函數的函數體語句,funcName就是所創建函數的名稱。可以不指定任何參數創建一個空函數,不指定funcName創建一個匿名函數。
需要注意的是,p1到pn是參數名稱的列表,即p1不僅能代表一個參數,它也可以是一個逗號隔開的參數列表,例如下面的定義是等價的:
new Function("a", "b", "c", "return a+b+c")
new Function("a, b, c", "return a+b+c")
new Function("a,b", "c", "return a+b+c")
函數的本質是一個內部對象,由JavaScript解釋器決定其運行方式。并且可直接在函數聲明后面加上括號就表示創建完成后立即進行函數調用,例如:
var i=function (a,b){
return a+b;
}(1,2);
alert(i);
這段代碼會顯示變量i的值等于3。i是表示返回的值,而不是創建的函數,因為括號“(”比等號“=”有更高的優先級。
三、匿名函數和有名函數的區別
匿名函數必須先定義后調用,有名函數可以先調用,后定義。
A)匿名(這段語句將產生func未定義的錯誤)
<script>
func();
var func = function() {
alert(1);
}
< /script>
B)有名(輸出1)
<script>
func();
function func() {
alert(1);
}
< /script>
這是因為JS解釋器是分段分析執行的。并且,在同一段中,有名函數會優先被分析。并且同名函數后面的覆蓋前面的。
而且,下面這段代碼也是合法的:
<script>
function myfunc ()
{
alert("hello");
};
myfunc(); //這里調用myfunc,輸出yeah而不是hello
function myfunc ()
{
alert("yeah");
};
myfunc(); //這里調用myfunc,輸出yeah
</script>
如果要讓上述代碼的第一次調用輸出“hello”,可以將它們分為兩段:
<script>
function myfunc ()
{
alert("hello");
};
myfunc(); //這里調用myfunc,輸出hello
< /script>
<script>
function myfunc ()
{
alert("yeah");
};
myfunc(); //這里調用myfunc,輸出yeah
</script>
下面的代碼輸出“hello”
<script>
function myfunc ()
{
alert("hello");
};
< /script>
<script>
myfunc(); //輸出“hello”
</script>
<script>
function myfunc ()
{
alert("yeah");
};
</script>
下面的代碼輸出“yeah”
<script>
function myfunc ()
{
alert("hello");
};
< /script>
<script>
function myfunc ()
{
alert("yeah");
};
</script>
<script>
myfunc(); //輸出“yeah”
</script>
從上面對段的位置變化導致輸出變化很清楚的解釋了JS解釋器分段分析執行的本質。