比較常見的javascript中定義函數的差異主要透過以下三個面向給大家講解,需要的朋友參考下吧
1:呼叫關鍵字function來建構
如:
function distance(x1,x2,y1,y2) { var dx=x2-x1; var dy=y2-y1; return Math.sqrt(dx*dx+dy*dy); }
2:使用Function()建構子
如:
var f=new Function*"x","y","return x*y");
這行程式碼建立了一個新函數,該函數和你所熟悉的語法定義的函數基本上時等價的:
function f(x,y) { return x*y; }
Functino()建構子可以接受任意多個字串參數。它的最後一個參數時函數的主體,其中可以包含任何JavaScript語句,語句之間以分號分隔。其他的參數都是用來說明函數要定義的形式參數名的字串。如果你定義的函數沒有參數,那麼可以只給建構函式傳遞一個字串(即函數的主體)。
注意,傳遞給建構函式Function()的參數中沒有一個用來說明它要建立的函式名稱。用Function()建構函數所建立的未命名函數有時會被成為「匿名函數」。
你可能很想知道Function()建構子的用途是什麼。為什麼不能只用function語句來定義所有的函數呢?原因是Function()建構函數允許我們動態地建立和編譯一個函數,它不會將我們限制在function語句預先編譯的函數體中。這樣做帶來的負面影響效應就是每次呼叫一個函數時,Function()建構子都要對它進行編譯。因此,在循環體中或在經常使用的函數中,我們不應該頻繁地呼叫這個構造函數。
使用Function()建構函數的另一個原因是它能夠將函數定義為JavaScript表達式的一部分,而不是將其定義一個語句,這種情況下使用它就顯得比較的方面,甚至可以說精緻。
3:函數直接量
函數直接量是一個表達式,它可以定義匿名函數。函數直接量的語法和function語句非常相似,只不過它被用作表達式,而不是用作語句,也無需指定函數名。下面的三行程式碼分別使用function()語句、Funciont()建構子和函式直接量定義了三個基本上相同的函數:
function f(x){return x*x}; var f=new Function("x","return x*x;"); var f=function(x){reurn x*x};
雖然函數直接量創建的是未命名函數,但是它的語法也規定它可以指定函數名,這在編寫調用自身的遞歸函數時非常有用。
例如:
var f=function fact(x){if(x<=1)return 1;else return x*fact(x-1);};
上面的程式碼定義了一個未命名函數,並對它的參考儲存在變數f中。它並沒有真正的創建一個名為fact()的函數,只是允許函數體用這個名字來引用自身。但是要注意,JavaScript1.5之前的版本中沒有正確實作這種命名的函數直接量。
函式直接量的用法和用Function()建構子建立函式的方法非常相似。由於它們都是由JavaScript的表達式創建的,而不是由語句創建的,所以使用它們的方式也就更加靈活,尤其適用於那些只使用一次,而且無需命名的函數。例如,一個使用函數直接量表達式指定的函數可以儲存在一個變數中、傳遞給其他的函數甚至直接呼叫:
a[0]=function(x){return x*x;};//定义一个函数并保存它 a.sort(function(a,b){return a-b;});//定义一个函数;把它传递给另一个函数 var tensquared=(function(x){return x*x;})(10);
和Function()构造函数一样,函数直接量创建的是未命名函数,而且不会自动地将这个函数存储在属性中。但是,比起Function()构造函数来说,函数直接量有一个重要的优点。由Function()构造函数创建的函数的主体必须用一个字符串说明,用这种方式来表达一个长而复杂的函数是狠笨拙的。但是函数直接量的主体使用的却是标准的JavaScript语法。而且函数直接量只被解析一次,而作为字符串传递给Function()构造函数的JavaScript代码则在每次调用构造函数时只需被解析一次和编译一次。
在JavaScript1.1中,可以使用构造函数Function()来定义函数,在JavaScript1.2和其后的版本中,还可以使用函数直接量来构造函数。你应该注意这两种方法之间的重要差别。
首先,构造函数Function()允许在运行时动态地创建和编译JavaScript代码。但是函数直接量却是函数结构的一个静态部分,就像function语句一样。
其次,作为第一个差别的必然结果,每次调用构造函数Function()时都会解析函数体并且创建一个新东汉数对象。如果对构造函数的调用出现在一个循环中,或者出现在一个经常被调用的函数中,这种方法的效率非常低。另一个方面,函数直接量或出现在循环和函数中的嵌套函数不是在每次调用时都被重新编译,而且每当遇到一个函数直接量时也不创建一个新的函数对象。
Function()构造函数和函数之间量之间的第三点差别是,使用构造函数Function()创建的函数不使用词法作用域,相反的,它们总是被当作顶级函数来编译,就像下面代码所说明的那样:
var y="global"; function constructFunction() { var y="local"; return new Function("return y");//不捕捉局部作用域。 } //这行代码将显示"global",因为Function()构造函数返回的函数并不使用局部作用域。 //假如使用一个函数直接量,这行代码则可能显示"local"。 alert(constructFunction());