1. 程式人生 > >JavaScript之callback回調函數

JavaScript之callback回調函數

herf 關鍵字 javascrip 是把 ack 編程 數組 func button

以下內容借鑒老鳥的經驗和知識,結合自己的學習,精髓的總結。

一句話:對於以後研究node 和那些熱門的前端框架 很有幫助。如果你看過這個文章,對於你來說是質的突變。

理解javascript中的回調函數(`callback`),希望對你有所幫助。

在JavaScrip中,function是內置的類對象,也就是說它是一種類型的對象,和其它String、Array、Number、Object類的對象一樣用於內置對象的管理。

function實際上是一種對象,它可以“存儲在變量中,通過參數傳遞給(別一個)函數(function),在函數內部創建,從函數中返回結果值”。

函數式編程最主要的技術之一就是回調函數,實現回調函數就像傳遞一般的參數變量一樣簡單。

## 那麽第一個問題來了,什麽是回調?

回調函數被認為是一種高級函數,一種被作為參數傳遞給另一個函數(在這稱作`otherFunction`)的高級函數。回調函數會在`otherFunction`內被調用(或執行)。

回調函數的本質是一種模式(一種解決常見問題的模式),因此回調函數也被稱為回調模式。

>舉個列子:

var colors=[ ‘red‘, ‘yellow‘, ‘blue‘, ‘green‘];
colors.forEach(function(color,i){
    console.log( i + 1 + ‘.‘ + color)  // 控制臺輸出結果:1.red, 2.yellow, .blue, 4.green
})

這裏我們傳遞一個匿名函數給`foreach`方法,作為`foreach`的參數,傳遞了一個匿名的函數作為參數給另一個函數或方法。

>這裏舉一個 jquery 常用的回調函數:

<button class="btn">btn</button>

$(".btn").click(function() {  //匿名函數將延遲在click函數的函數體內被調用,即使沒有名稱,也可以被包含函數通過 arguments對象訪問。
alert("clicked"); });
}

同樣這裏 傳遞一個函數給click方法的參數,click方法將會調用(或執行)傳遞給他的回調函數。

## 講了這麽多,回調函數是怎麽實現的呢?

回調函數作為變量一樣使用,來作為另一個函數的參數,在另一個函數中作為返回的結果,在另一個函數中調用它。

這裏我們作為參數傳遞一個回調函數給另一個函數時,我們只傳遞了函數的定義並沒有在參數中執行它。

當函數(這裏指的是調用或者執行函數)擁有了參數中定義的回調函數後,它可以在任何時候調用。

也說明了回調函數不是立即執行的,而是在包含函數的函數體內指定的位置回調它。

>再來看下這個例子

function sum(callback) {
    //Array.prototype.slice.call(arguments,1)能將具有length屬性的對象轉成數組,arguments是一個關鍵字,代表當前參數,在javascript中雖然arguments表面上以數組形式來表示,但實際上沒有原生數組slice的功能。
//這裏使用call方法算是對arguments對象不完整數組功能的修正。
//slice返回一個數組,該方法只有一個參數的情況下表示除去數組內的第一個元素。就本上下文而言,原數組的第一個參元數是函數名為add的回調函數,其後的元素才是處理函數所接納的參數列表。 var args = Array.prototype.slice.call(arguments, 1); //通俗的來講,這一行代碼的作用是把函數接受的所有的形參組成一個數組,刪除數組內的第一個元素,把數組賦值給args typeof callback === ‘function‘ && callback(args); //若參數中存在回調函數,把args作為形參傳給這一回調函數並執行。 console.log(args) } //把傳進來的數組內的所有元素進行相加 function add(options) { var totle = 0; options.map(function(item) { if (typeof item === ‘object‘ && Object.prototype.toString.call(item) === ‘[object Array]‘) { item.map(function(itemCell) { totle += itemCell }) } else { totle += item; } }) console.log(totle); } sum(add, 1, 2, 3, 4, 5, [10, 20])

來看下控制臺的輸出結果:

技術分享

Array(6)便是除回調函數外所有形參組成的數組,45是回調函數內對Array(6)內所有元素進行相加的結果。

> 回調函數是閉包的

當作為參數傳遞另一個函數時,回調函數將在包含函數函數體內的某個位置被執行,就像回調函數在包含函數的函數體內定義一樣。這意味著回調函數是閉包的.。

## 實現回調函數的基本原則

> 使用命名函數或匿名函數作為回調

在前面的jQuery和forEach的例子中,我們在包含函數的參數中定義匿名函數,這是使用回調函數的通用形式之一。

另一個經常被使用的形式是定義一個帶名稱的函數,並將函數名作為參數傳遞給另一個函數,例如:

    function fn() {
        console.log("帶名稱函數")
    }

    function test1(fn) {
        fn();
    }

    test1(fn);

JavaScript之callback回調函數