微信小程序開發教程(基礎篇)4-關於回調函數,匿名函數,閉包的雜談

嚴格來講,這不能算是一篇微信小程序教程,不過會使用到上一篇中的app.js代碼做爲示例,姑且充個數吧。javascript

回調函數

回調函數,對於初入編程這一行的同窗可能會有些難以理解,畢竟回調函數的使用和程序順序執行的直觀流程是相悖的。java

想象你定了一個外賣,一種是你定時去查看外賣有沒有到,一種是你出示電話號碼給外賣員,到達的時候電話通知你。c++

很容易能夠看出第二種是更加高效的方案,其實這種通知機制應用到編程領域,就是回調函數了。編程

熟悉win32開發的同窗應該知道,典型的windows程序框架就是一個消息循環外加一個窗口過程函數。其中windows系統接管消息接受,以後調用開發者的窗口過程函數來完成具體的消息處理邏輯。窗口過程函數就是一個回調函數。小程序

爲何須要回調函數

以上面的 win32程序爲例。咱們知道出於安全性考慮,windows操做系統是不容許開發者直接訪問硬件資源的。微軟的開發者提供了api來處理消息循環,可是具體消息的響應邏輯須要開發者來提供,這種情形下,回調函數就是很好的實現方案。windows

再舉一個例子,想象你參與一個手機設備管理軟件項目的開發工做,你負責底層設備通訊模塊。當用戶插入設備到電腦中時,你須要通知上層的模塊進行處理。出於靈活性和通用性的考慮,你不可能將設備鏈接時的處理邏輯放在你負責的模塊中,此時能夠由上層調用者提供一個回調函數,在設備鏈接時你的模塊調用回調函數便可。微信小程序

關於回調函數,有一個所謂的好萊塢準則:Don't call me; I'll call you!api

匿名函數

在c,c++等語言中,當須要使用回調函數時,須要預先定義一個函數體。而回調函數一般只是提供給其它模塊進行調用,爲了簡化編碼,後續的javascript等腳本語言中提供了對匿名函數的支持。(注: 新的c++標準也開始支持匿名函數,稱爲Lambda函數)安全

getUserInfo:function(cb){
    var that = this
    if(this.globalData.userInfo){
      typeof cb == "function" && cb(this.globalData.userInfo)
    }else{
      //調用登陸接口
      wx.login({
        success: function () {
          wx.getUserInfo({
            success: function (res) {
              that.globalData.userInfo = res.userInfo
              typeof cb == "function" && cb(that.globalData.userInfo)
            }
          })
        }
      })
    }
  },

上面的代碼來自於上一篇教程中的app.js,在調用wx.login時,傳遞了一個匿名函數進行調用成功後的邏輯處理,就是success後面的部分。能夠看到這裏只有函數定義而沒有函數名稱,所以除了做爲回調函數外,也沒法在其它地方調用該函數。微信

實際上匿名函數僅僅是一種編碼簡化而已,不過它帶來的好處卻不單單是減小編碼而已。

閉包

在編程技術中,閉包應該屬於較高級的技術了。
當使用回調函數時,一般會涉及到一些上下文的傳遞。在c/c++等語言中,會使用全局變量或堆內存來傳遞上下文。全局變量的缺點很明顯,而堆內存又很容易發生內存泄漏。而在更高級的腳本語言中,能夠經過閉包技術來輕鬆的完成上下文傳遞。

以上面的代碼爲例,在回調函數中執行了that.globalData.userInfo = res.userInfo來保存用戶信息,其中that變量由var that = this賦值,所以該變量指向app對象自己,因此才能成功保存用戶信息。

咱們能夠看到that對象是getUserInfo方法棧上的變量,若是沒有閉包技術,此處的匿名回調函數是不能直接使用that變量的,就須要將app對象傳遞給回調函數(全局變量或函數參數的方式),而在閉包技術的支持下,回調函數能夠像使用函數內部變量同樣來訪問that變量,語法上便捷了許多。

相關文章
相關標籤/搜索