摘要:只有兩個(gè)參數(shù),并且第二個(gè)參數(shù)必須為數(shù)組,數(shù)組中的所有元素一一對應(yīng)原函數(shù)的參數(shù)。語法語法語法調(diào)用調(diào)用后立即執(zhí)行原函數(shù)。
call(),apply(),bind() 函數(shù)大家可能都有所了解,但是在平時(shí)搬磚過程中很可能或者基本沒用過,學(xué)過但都淡忘了。
但是在大量第三方的框架(庫),甚至js自己都在 源碼中大量使用 call,apply 函數(shù)。所以今天和大家仔細(xì)討論下它們在 開發(fā)中的應(yīng)用場景 。
1 . 它們是啥意思 1.1 作用他們的作用都是改變函數(shù)內(nèi)部的this。
這三個(gè)函數(shù)都是函數(shù)對象的方法,也就是說只有函數(shù)才可以直接調(diào)用這些方法。
ps:call,apply,bing屬于this顯示綁定,還有好幾種其他的this綁定方式,感興趣的可以點(diǎn)這里。
1.2 三者區(qū)別參數(shù): 三個(gè)函數(shù)的第一個(gè)參數(shù)都是需要綁定的 this。
call: 可以有n個(gè)參數(shù),從第二個(gè)參數(shù)開始的所有參數(shù)都是原函數(shù)的參數(shù)。
`apply`:只有兩個(gè)參數(shù),并且第二個(gè)參數(shù)必須為數(shù)組,數(shù)組中的所有元素一一對應(yīng)原函數(shù)的參數(shù)。 `bind`: 只有一個(gè)參數(shù),即要綁定的this。
call 語法: foo.call(this, arg1,arg2, ... ,argn ); apply 語法: foo.apply(this, [ arg1,arg2, ... ,argn ] ); bind 語法: foo.bind(this);
調(diào)用:
call,apply: 調(diào)用后立即執(zhí)行原函數(shù)。
`bind`: 調(diào)用后返回已經(jīng)綁定好this的函數(shù)。
小例子一枚:
function foo(a,b){ console.log(a+b); } foo.call(null,"海洋","餅干"); // 海洋餅干 這里this指向不重要就寫null了 foo.apply(null, ["海洋","餅干"] ); // 海洋餅干 var fun = foo.bind(null); fun("海洋","餅干"); // 海洋餅干2 .它們能干啥事
這是我們今天討論的主題,這三個(gè)函數(shù)如何應(yīng)用?什么情況下使用?能改變this指向又能咋滴?
2 .1 處理偽數(shù)組 (最常用)先考慮一個(gè)問題,如果你使用var arr = document.getElementsByTagName("li")獲取了5個(gè)li元素,你現(xiàn)在需要獲取其中的第2,3,4三個(gè)元素,你會(huì)怎么做?
這樣arr.slice(1,4);? 啊哦,TypeError -- arr.slice is not a function(slice不是函數(shù)),數(shù)組操作在日常搬磚中非常常見,我見過最傻的解決這個(gè)問題的方式是使用循環(huán),將需要的元素一個(gè)個(gè)添加到一個(gè)新數(shù)組里0.0,下面我介紹的方法完全可以在實(shí)戰(zhàn)中使用,可以給你的代碼加分哦,非常方便簡潔(中高級前端程序員中,算是基本操作了)。
先要介紹一個(gè)概念( 偽數(shù)組 ),這也是為什么我們剛剛slice切割數(shù)組時(shí)出錯(cuò)的原因: (對新手來說算是干貨了,知道的可以跳過)
什么是偽數(shù)組?( 字面的意思已經(jīng)呼之欲出了 )
有l(wèi)ength屬性
能按索引存儲數(shù)據(jù)
能像遍歷數(shù)組一樣來遍歷
不能使用數(shù)組的push()、slice()等方法
簡單來說就是可以像數(shù)組一樣操作的對象,但是沒有數(shù)組的方法。
js中存在大量偽數(shù)組,如 :
1. function的arguments對象。 2. getElementsByName(),getElementsByTagName(),childNodes/children 等方法的返回值。 3. 還有比較常見的jquery,使用它獲取的元素也是偽數(shù)組。
回到原來的問題,如何截取偽數(shù)組中的元素:偽數(shù)組沒有這些方法,我們"借用"Array的slice不就行了
[].slice.call(arr,1,4); // 推薦寫法
不想借用你可以直接給偽數(shù)組添加一個(gè)slice函數(shù),如
arr.slice = [].slice; arr.slice(1,4);
當(dāng)然,"借用" 更方便,直接添加會(huì)導(dǎo)致偽數(shù)組對象"污染"。
如果可以隨意改變原對象,可以 直接將其轉(zhuǎn)成真正的數(shù)組對象。
[].slice.call(arr);2 .2 繼承
繼承方式多種多樣,我們現(xiàn)在討論的這種是其中很重要的一種實(shí)現(xiàn)方式,用call實(shí)現(xiàn) js 構(gòu)造函數(shù)繼承 。
單繼承
function person(name){ this.name = name } function man(name){ this.age = "男"; person.call(this,name); // 繼承 man } var me = new man("海洋餅干"); console.log(me.name,me.age); // "海洋餅干" "男"
多繼承
function person(name){ this.name = name } function man(name){ this.age = "男"; } function manProgrammer(name){ this.girlfriend = null; person.call(this,name); // 繼承 person man.call(this,name); // 繼承 man } var me = new manProgrammer("海洋餅干"); console.log(me.name,me.age,me.girlfriend); // "海洋餅干" "男" null2 .3 this 硬綁定 --- bind
將一個(gè)對象強(qiáng)制且永久性綁定到函數(shù)的this上,使用call,apply或者其他的綁定方式都無法改變(除了new綁定,當(dāng)然,可以手動(dòng)擼一個(gè)new都無法改變的硬綁定)
直接看例子:
var fun ; var obj = { a : 1, foo : function(){ var _this = this; //平時(shí)有沒有過這種寫法? 為了防止this指向問題 //將this賦值給一個(gè)變量,間接維持了this的安全性 fun = function(){ console.log(_this.a); } } } obj.foo(); fun(); // 1 var obj1 = { a : 2} obj.foo.call(obj1); // 直接修改_this所綁定的值,boom了 fun(); // 2
但是這種方法感覺上是在逃避問題,直接不使用this了 ? 這真的不是什么好的解決問題的態(tài)度。下面使用我們的bind來優(yōu)化一下:
var fun ; var obj = { a : 1, foo : function(){ // 不使用 _this, 避免無謂的變量聲明 fun = function(){ console.log(this.a); }.bind(this); // 代碼很簡潔,很漂亮(b格) } } var obj1 = { a : 2} obj.foo(); fun(); // 1 fun.call(obj1); // 1 call ,apply等綁定 無法修改 // 這里和上面call的位置不同是因?yàn)閠his所處于不同的位置
這樣替代 _this 很規(guī)(zhuang)范(b)呢
ps:call,apply,bing屬于this顯示綁定,還有好幾種其他的this綁定方式,感興趣的可以點(diǎn)這里。
2 .4 取數(shù)組最大最小值Math.max和min方法,接收多個(gè)參數(shù),比較出極值,這里用到apply的一個(gè)默認(rèn)功能:展開數(shù)組,傳入一個(gè)數(shù)組參數(shù)就可以默認(rèn)將這個(gè)數(shù)組轉(zhuǎn)成一個(gè)個(gè)參數(shù)的形式賦給原函數(shù)
var num = [6,9,-3,-5]; console.log(Math.max.apply(Math,num)); // 9 等價(jià) console.log(Math.max(6,9,-3,-5)); console.log(Math.min.apply(Math,num)); // -5 等價(jià) console.log(Math.min(6,9,-3,-5));2 .5 合并數(shù)組
合并數(shù)組常見有三種方式,1.循環(huán) 2.Array的concat() 3. 使用apply()合并
這里是使用最簡便的apply
var a = [1,2,3]; var b = [4,5,6]; [].push.apply(a,b); // 借用數(shù)組的push方法 等價(jià) a.push(4,5,6); console.log(a); // [1, 2, 3, 4, 5, 6]
覺得對你有幫助點(diǎn)個(gè)贊唄555
大家有什么實(shí)用點(diǎn)的黑科技?xì)g迎私信評論 分享,我會(huì)貼上id和你的分享 >_<
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/51309.html
摘要:只有兩個(gè)參數(shù),并且第二個(gè)參數(shù)必須為數(shù)組,數(shù)組中的所有元素一一對應(yīng)原函數(shù)的參數(shù)。語法語法語法調(diào)用調(diào)用后立即執(zhí)行原函數(shù)。 call(),apply(),bind() 函數(shù)大家可能都有所了解,但是在平時(shí)搬磚過程中很可能或者基本沒用過,學(xué)過但都淡忘了。 但是在大量第三方的框架(庫),甚至js自己都在 源碼中大量使用 call,apply 函數(shù)。所以今天和大家仔細(xì)討論下它們在 開發(fā)中的應(yīng)用場景 ...
摘要:前端日報(bào)精選等新方法簡介寫作建議和性能優(yōu)化小結(jié)前端面試之篇第期關(guān)于雪碧圖預(yù)處理和后處理方案的討論你的網(wǎng)站可以一鍵變色嗎中文譯內(nèi)存管理碰撞課程掘金阿里前端面試點(diǎn)目標(biāo),想成為一名好的前端工程師那些事函數(shù)能干啥如何在日常搬磚中使用最全, 2017-09-28 前端日報(bào) 精選 before(),after(),prepend(),append()等新DOM方法簡介css寫作建議和性能優(yōu)化小結(jié)前...
摘要:哪吒社區(qū)技能樹打卡打卡貼函數(shù)式接口簡介領(lǐng)域優(yōu)質(zhì)創(chuàng)作者哪吒公眾號作者架構(gòu)師奮斗者掃描主頁左側(cè)二維碼,加入群聊,一起學(xué)習(xí)一起進(jìn)步歡迎點(diǎn)贊收藏留言前情提要無意間聽到領(lǐng)導(dǎo)們的談話,現(xiàn)在公司的現(xiàn)狀是碼農(nóng)太多,但能獨(dú)立帶隊(duì)的人太少,簡而言之,不缺干 ? 哪吒社區(qū)Java技能樹打卡?【打卡貼 day2...
閱讀 2101·2021-11-19 09:58
閱讀 1700·2021-11-15 11:36
閱讀 2867·2019-08-30 15:54
閱讀 3382·2019-08-29 15:07
閱讀 2759·2019-08-26 11:47
閱讀 2804·2019-08-26 10:11
閱讀 2496·2019-08-23 18:22
閱讀 2743·2019-08-23 17:58