js中apply和call的理解與使用方法
前言
關于call和apply,以前也思考良久,很多時候都以為記住了,但是,我太難了。今天我特地寫下筆記,希望可以完全掌握這個東西,也希望可以幫助到任何想對學習這個東西的同學。
一.apply函數(shù)定義與理解,先從apply函數(shù)出發(fā)
在MDN上,apply的定義是:
“apply()方法調用一個具有給定this值的函數(shù),以及作為一個數(shù)組(或類似數(shù)組對象)提供的參數(shù)?!?/p>
我的理解是:apply的前面有個含有this的對象,設為A,apply()的參數(shù)里,也含有一個含有this的對象設為B。則A.apply(B),表示A代碼執(zhí)行調用了B,B代碼照常執(zhí)行,執(zhí)行后的結果作為apply的參數(shù),然后apply把這個結果所指代表示的this替換掉A本身的this,接著執(zhí)行A代碼。
比如:
var aa = { _name:111, _age:222, _f:function(){ console.log(this) console.log(this._name) } } var cc = { _name:0, _age:0, _f:function(){ console.log(this) console.log(this._name) } } cc._f.apply(aa)//此時aa表示的this就是aa本身 cc._f.apply(aa._f)//此時aa._f表示的this就是aa._f本身 /** * 此時aa._f()表示的this,就是執(zhí)行后的結果本身。aa._f()執(zhí)行后,沒有返回值,所以應該是undefined,而undefined作為call和apply的參數(shù)時,call和apply前面的方法 cc._f 的this會替換成全局對象window。 * 參考MDN:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/apply 的參數(shù)說明 */ cc._f.apply(aa._f())
執(zhí)行結果:
1.參數(shù)為aa
這兩行的打印的都是來自 cc._f 方法內(nèi)的那兩句console 。aa的時候算是初始化,里面的 aa._f 方法沒有執(zhí)行。
2.參數(shù)為aa.f
這兩行的打印的都是來自 cc._f 方法內(nèi)的那兩句console 。aa.f 的時候應該也算是初始化,或者是整個函數(shù)當參數(shù)傳但是不執(zhí)行這個參數(shù),即 aa._f 方法沒有執(zhí)行。
3.參數(shù)為aa.f()
這四行的打印,前面兩行來自 aa._f() 方法執(zhí)行打印的;后面兩行是來自cc._f()方法打印的。
后兩行解析:aa._f()執(zhí)行后,沒有返回值,所以是undefined,在apply執(zhí)行解析后,cc._f()的this變成的window,所以打印了window。window里面沒有_name這個屬性,所以undefined。
二.apply與call的區(qū)分
1.apply()
A.apply(B, [1,2,3]) 后面的參數(shù)是arguments對象或類似數(shù)組的對象,它會被自動解析為A的參數(shù);
對于A.apply(B) / A.call(B) , 簡單講,B先執(zhí)行,執(zhí)行后根據(jù)結果去執(zhí)行A。這個時候,用A去執(zhí)行B的內(nèi)容代碼,然后再執(zhí)行自己的代碼。
比如:
var f1 = function(a,b){ console.log(a+b) } var f2 = function(a,b,c){ console.log(a,b,c) } f2.apply(f1,[1,2])//1 2 undefined
先執(zhí)行f1,f1執(zhí)行后(f1是f1,不是f1()執(zhí)行方法,所以console.log(a+b)這行代碼并沒有執(zhí)行,相當于,初始化了代碼f1),由于沒有返回值,所以結果是undefined,f2執(zhí)行的時候this指向window;參數(shù)中的 ” [1,2] “,解析后變成 f2 的參數(shù) “ 1,2,undefined ”,執(zhí)行f2方法后,打印出1,2,undefined三個值
2.call()
A.call(B, 1,2,3) 后面的參數(shù)都是獨立的參數(shù)對象,它們會被自動解析為A的參數(shù);
比如:
var f1 = function(a,b){ console.log(a+b) } var f2 = function(a,b,c){ console.log(a,b,c) } f2.call(f1,[1,2])//[1,2] undefined undefined f2.call(f1,1,2)//1 2 undefined
參數(shù)中的 ” [1,2] “,因為傳入了一個數(shù)組,相當于只傳入了第一個參數(shù),b和c參數(shù)沒有傳。解析后變成 f2 的參數(shù) “ [1,2],undefined ,undefined ”,執(zhí)行f2方法后,打印出 [1,2],undefined ,undefined 三個值。
三.apply與call帶來的便利
1. push();
push參數(shù)是類似(a,b,c,d,e)如此傳輸?shù)?,如果在一個數(shù)組的基礎上進行傳輸另一個數(shù)組的內(nèi)容,可以如下:
//apply用法 var arr = new Array(1,2,3) var arr1 = new Array(11,21,31) Array.prototype.push.apply(arr,arr1) console.log(arr)//[1, 2, 3, 11, 21, 31] //call用法 var arr = new Array(1,2,3) var arr1 = new Array(11,21,31) Array.prototype.push.call(arr,arr1[0],arr1[1],arr1[2]) console.log(arr)//[1, 2, 3, 11, 21, 31]
2. 數(shù)組利用Math求最大和最小值
apply和call的第一個參數(shù),如果是null或者undefined,則apply或call前面的函數(shù)會把this指向window
//apply的用法 var _maxNum = Math.max.apply(null,[1,3,2,4,5]) console.log(_maxNum)//5 var _minNum = Math.min.apply(null,[1,3,2,4,5]) console.log(_minNum)//1 //call的用法 var _maxNum = Math.max.call(null,1,3,2,4,5) console.log(_maxNum)//5 var _minNum = Math.min.call(null,1,3,2,4,5) console.log(_minNum)//1
四.總結
簡而言之,apply和call函數(shù)的第一個參數(shù)都是用來替換this指向的對象;apply的第二個參數(shù)使用arguments或者類似數(shù)組的參數(shù)進行傳參,call的第二個或以上的參數(shù),使用獨立單位,一個一個進行傳參;執(zhí)行順序是apply或call的第一個參數(shù)先執(zhí)行得到結果,然后執(zhí)行apply或call前面的函數(shù),執(zhí)行的時候用已經(jīng)執(zhí)行的結果所指代的this去執(zhí)行。apply和call的使用除了參數(shù)上的使用方式不同外,功能是一模一樣的。
好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對腳本之家的支持。
- JavaScript中的this/call/apply/bind的使用及區(qū)別
- javascript中call,apply,callee,caller用法實例分析
- JS中call()和apply()的功能及用法實例分析
- js的繼承方法小結(prototype、call、apply)(推薦)
- javascript中call()、apply()的區(qū)別
- js中apply()和call()的區(qū)別與用法實例分析
- JavaScript函數(shù)apply()和call()用法與異同分析
- 詳解JS中的this、apply、call、bind(經(jīng)典面試題)
- Javascript call及apply應用場景及實例
相關文章
JavaScript實現(xiàn)倒計時代碼段Item1(非常實用)
現(xiàn)今團購網(wǎng)、電商網(wǎng)、門戶網(wǎng)等,常使用時間記錄重要的時刻,如時間顯示、倒計時差、限時搶購等,本文分析不同倒計時效果的計算思路及方法,掌握日期對象Date,獲取時間的方法,計算時差的方法,實現(xiàn)不同的倒時計效果2015-11-11Javascript Request獲取請求參數(shù)如何實現(xiàn)
使用Javascript Request獲取參數(shù)的時候總是提示出錯,本文為此問題提供詳細的解決方案,需要了解的朋友可以參考下2012-11-11javascript Array數(shù)組對象的擴展函數(shù)代碼
我們經(jīng)常給 String,Function,Array 的原型加上自定義的擴展函數(shù),比如去除字符串空格,數(shù)組排序等2010-05-05關于layui的下拉搜索框異步加載數(shù)據(jù)的解決方法
今天小編就為大家分享一篇關于layui的下拉搜索框異步加載數(shù)據(jù)的解決方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09如何確保JavaScript的執(zhí)行順序 之實戰(zhàn)篇
我曾在文章《如何在多個頁面使用同一個HTML片段 - 續(xù)》的最后提到JavaScript順序執(zhí)行的特性。雖然現(xiàn)代瀏覽器可以并行的下載JavaScript(部分瀏覽器),但考慮到JavaScript的依賴關系,他們的執(zhí)行依然是按照引入順序進行的。2011-03-03JavaScript數(shù)據(jù)存儲 Cookie篇
這篇文章主要為大家介紹了JavaScript數(shù)據(jù)存儲 Cookie篇,感興趣的朋友可以參考一下2016-07-07Bootstrap進度條與AJAX后端數(shù)據(jù)傳遞結合使用實例詳解
這篇文章主要介紹了Bootstrap進度條與AJAX后端數(shù)據(jù)傳遞結合使用,需要的朋友可以參考下2017-04-04JavaScript獲取時區(qū)實現(xiàn)過程解析
這篇文章主要介紹了JavaScript獲取時區(qū)實現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-09-09解決JSON.stringify()自動將中文轉譯成unicode的問題
下面小編就為大家分享一篇解決JSON.stringify()自動將中文轉譯成unicode的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-01-01