匿名函數與巢狀函數
在JavaScript可以宣告一個沒有名稱的函數,稱為匿名函數(Anonymouse Function)。同時JavaScript也允許在函數內部宣告函數,稱為巢狀函數(Nested Function),巢狀函數的作用域為整個父函數。
在前函數宣告的部分看到了匿名函數和巢狀函數的一種用法,由於匿名函數沒有名稱,不會引入新的變數污染情境環境,而且會帶來新的變數作用域,因此匿名函數常被用來防止全域環境污染。
JavaScript運行時中有一個特殊的全域環境(global object),這個物件上面存放全域的函數和變量,實際開發中常會使用若干第三方的函式庫或多個js文件,若不小心在全域物件引入重複的變數或函數聲明,則會造成程式碼執行混亂。例如先後引入兩個js文件,分別定義了自己的函數log作為內部使用,則第二引入的函數會覆蓋第一個的定義且不會拋出任何錯誤,在後續的執行中調用log函數可能會造成錯誤。這時候使用一個匿名函數將整個js內的邏輯包裝起來,就可以避免這種錯誤,這種方法已經被絕大多數開源js庫使用。
(function() { // 匿名函数 function log(msg) { console.log(msg); } // 其他代码 }()); // 立即执行
以上程式碼就是一個簡單的範例,log函數的作用域被限制在這個匿名函數之內,而匿名函數則因為被外面一對小括號()包括起來,形成一個函數表達式,表達式的值是一個函數,緊接著一對小括號表示立即執行這個函數,讓原有的程式碼正常執行一次。不過,這種方式宣告的函數、透過var宣告的變數等等都是內部的,不能被任何匿名函數以外的程式碼存取。如果你需要對外暴露一些函數作為介面的話有以下幾種方法:
var mylib = (function(global) { function log(msg) { console.log(msg); } log1 = log; // 法一:利用没有var的变量声明的默认行为,在log1成为全局变量(不推荐) global.log2 = log; // 法二:直接在全局对象上添加log2属性,赋值为log函数(推荐) return { // 法三:通过匿名函数返回值得到一系列接口函数集合对象,赋值给全局变量mylib(推荐) log: log }; }(window));
高階函數(High-order Function)
如果函數作為參數或傳回值使用時,就稱為高階函數,JavaScript中的函數都可以當作高階函數來使用,這也是第一類函數的特徵。下面我們就分別分析一下這兩種使用方法。
function negative(n) { return -n; // 取n的相反值 } function square(n) { return n*n; // n的平方 } function process(nums, callback) { var result = []; for(var i = 0, length = nums.length; i < length; i++) { result[i] = callback(nums[i]); // 对数组nums中的所有元素传递给callback进行处理,将返回值作为结果保存 } return result; } var nums = [-3, -2, -1, 0, 1, 2, 3, 4]; var n_neg = process(nums, negative); // n_neg = [3, 2, 1, 0, -1, -2, -3, -4]; var n_square = process(nums, square); // n_square = [9, 4, 1, 0, 1, 4, 9, 16];
以上程式碼展示了把函數作為參數傳入另一個函數process呼叫的範例,在process函數的實作中,把callback當作一個黑盒子看待,負責把參數傳給它,然後取得返回值,在呼叫之前並不清楚callback的具體實作。只有當執行到20行和22行時,callback才分別代表negative或square,分別對每個元素進行相反值或平方值的運算。
function generator() { var i = 0; return function() { return i++; }; } var gen1 = generator(); // 得到一个自然数生成器 var gen2 = generator(); // 得到另一个自然数生成器 var r1 = gen1(); // r1 = 0 var r2 = gen1(); // r2 = 1 var r3 = gen2(); // r3 = 0 var r4 = gen2(); // r4 = 1
上面的程式碼展示了把函數當作傳回值的範例,generator是一個自然數產生器函數,而回傳值是一個自然數產生函數。每次呼叫generator時都會把一個匿名函數當作結果傳回,這個匿名函數在被實際呼叫時依序傳回每個自然數。
以上是JavaScript函數進階學習與進階函數實例程式碼詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!