這篇文章為大家帶來了關於JavaScript的相關知識,其中主要介紹了回調函數的相關內容,包括了什麼是回呼函數、回調函數有哪些特點、回調函數中this指向問題,下面一起來看一下,希望對大家有幫助。
【相關推薦:JavaScript影片教學、web前端】
##1.什麼是回呼函數(callback)呢? 把函數當作一個參數傳到另外一個函數中,當需要用這個函數是,再回呼運行()這個函數.回呼函數是一段可執行的程式碼段,它作為一個參數傳遞給其他的程式碼,其作用是在需要的時候方便呼叫這段(回呼函數)程式碼。 (作為參數傳遞到另外一個函數中,這個作為參數的函數就是回呼函數)
理解:函數可以作為一個參數傳遞到另外一個函數中。<script> function add(num1, num2, callback) { var sum = num1 + num2; callback(sum); } function print(num) { console.log(num); } add(1, 2, print); //3 </script>分析:add(1, 2, print);中,函數print作為一個參數傳入到add函數中,但並不是馬上起作用,而是var sum = num1 num2;運行完之後需要列印輸出sum的時候才會呼叫這個函數。 (這個作為參數傳遞到另外一個函數中,這個作為參數的函數就是回呼函數.匿名回呼函數:
<script> function add(num1, num2, callback) { var sum = num1 + num2; callback(sum); } add(1, 2, function (sum) { console.log(sum); //=>3 }); </script>2.回呼函數有哪些特點?1.不會立即執行回呼函數作為參數傳遞給一個函數的時候,
傳遞的只是函數的定義並不會立即執行。和普通的函數一樣,回呼函數在呼叫函數數中也要透過()運算子呼叫才會執行
。
<script> function add(num1, num2, callback) { var sum = num1 + num2; //判定callback接收到的数据是一个函数 if (typeof callback === 'function') { //callback是一个函数,才能当回调函数使用 callback(sum); } } </script>3.回呼函數中this的指向問題注意在
回呼函數呼叫時this的執行上下文並不是回調函數定義時的那個上下文,而是呼叫它的函數所在的上下文。
舉例:<script> function createData(callback){ callback(); } var obj ={ data:100, tool:function(){ createData(function(n){ console.log(this,1111); //window 1111 }) } } obj.tool(); </script>分析:this指向是
離它最近的或是巢狀層級的function/方法的呼叫者 ,這裡離它最近的function是
function(n),會回到上面的callback()中,這時候呼叫者就不是obj而是window。 解決回呼函數this指向的方法1:箭頭函數回呼函數(分析:回呼函數用箭頭函數寫之後,this指向很明確,就是離它最近的或是巢狀層級的function/方法的呼叫者,所以這裡是obj 。解決回呼函數this指向的方法2:var self = this;若回呼函數是普通函數時)當參數傳入另外的函數時,若不知道這個函數內部怎麼調用回呼函數,就會出現回呼函數中的this指向不明確的問題(就比如上面例子中this指向的不是obj而是window)。所以 把箭頭函數當回呼函數,然後作為參數傳入另外的函數中就不會出現this指向不明的問題。
<script> function createData(callback){ callback(); } var obj ={ data:100, tool:function(){ createData((n)=>{ this.data = n; }) } } obj.tool(); console.log(obj.data); </script>
<script> function createData(callback){ callback(999); } var obj ={ data:100, tool:function(){ var self = this; //这里的this指向obj,然后当一个变量取用 createData(function(n){ self.data = n; }) } } obj.tool(); console.log(obj.data); </script>4.為什麼要用到回呼函數?有一個非常重要的原因—
JavaScript 是事件驅動的語言。這意味著,JavaScript 不會因為要等待一個回應而停止目前運行,而是在監聽其他事件時繼續執行。來看一個基本的範例:
<script> function first() { console.log(1); } function second() { console.log(2); } first(); second(); </script>分析:如你所料,
first 函數先被執行,接著
second 被執行- 控制台輸出:1 2
函數 first 包含某種無法立即執行的程式碼
會如何呢?例如我們必須發送請求然後等待回應的 API 請求?為了模擬這個狀況,我們將使用 setTimeout,它是一個在一段時間之後呼叫函數的 JavaScript 函數。我們將函數延遲500 毫秒模擬一個API 請求,新程式碼長這樣:
<script> function first() { // 模拟代码延迟 setTimeout(function () { //所以function(){console.log(1)}是回调函数 console.log(1); }, 500); } function second() { console.log(2); } first(); second(); </script>分析:這裡function(){console.log(1)}函數當作一個參數傳入setTimeout函數中,因為setTimeout是官方提供得一個函數,裡面有很多複雜的業務程序,所以函數function(){console.log(1)}傳入後,不一定馬上運行,要setTimeout裡面要運行到function(){console. log(1)}時才會執行該函數參數,那是不是整個程式就一直等setTimeout運行?不是的! ! !
整個程式運作結果為: 2 1 ,並不是原先的1 2 .即使我們先呼叫了 first()
函數,我們記錄的輸出結果卻在 second( )
函數之後。
這不是JavaScript 沒有按照我們想要的順序執行函數的問題,而是 JavaScript 在繼續向下執行 second()
之前沒有等待 first()
回應的問題。 回呼正是確保一段程式碼執行完畢之後再執行另一段程式碼的方式。
定義:回呼函數被認為是一種高階函數,一種被當作參數傳遞給另一個函數的高階函數。回呼函數的本質是一種模式(一種解決常見問題的模式),因此回呼函數也被稱為回呼模式。
簡而言之:一個函數在另一個函數中被呼叫。而且可以當參數傳給其他函數。
所以: 回呼函數和非同步運算的關係是沒有關係! ! !
那為什麼很多的非同步運算都有回填函數啊? ?
問:你所知道的非同步操作,是回呼的作用麼? ? ? 並不是。
回呼:更多的可以理解為一種商業邏輯把 非同步程式設計:JS程式碼的執行順序
簡單理解:callback 顧名思義##eg1:你點外賣,剛好你要吃的食物沒有了,於是你在店老闆那裡留下了你的電話,過了幾天店裡有了,店員就打了你的電話,然後你接到電話後就跑到店裡買了。在這個例子裡,你的電話號碼就叫回調函數,你把電話留給店員就叫登記回調函數,店裡後來有貨了叫做觸發了回調關聯的事件,店員給你打電話叫做調用回調函數,你到店裡去取貨叫做回應回調事件。
eg2:再例如,你發送一個axios 請求,請求成功之後,觸發成功的回呼函數,請求失敗觸發失敗的回呼函數。這裡面的回呼函數比較像是工具,後台透過這個工具告訴你,你成功了抑或是失敗了。
這裡面的所有非同步操作都和回呼沒關係,真正的非同步是then方法。【相關推薦:
JavaScript影片教學、web前端】
以上是JavaScript中的回呼函數詳細解析的詳細內容。更多資訊請關注PHP中文網其他相關文章!