摘要:首先,我們判斷是否存在方法,然后,若不存在,向?qū)ο蟮脑椭刑砑幼远x的方法。指向調(diào)用它的對象。總之三個的使用區(qū)別都是用來改變函數(shù)的對象的指向的第一個參數(shù)都是要指向的對象都可以利用后續(xù)參數(shù)傳參是返回對應(yīng)函數(shù),便于稍后調(diào)用,是立即調(diào)用
apply和call都是為了改變某個函數(shù)運行時的上下文而存在的(就是為了改變函數(shù)內(nèi)部this的指向),F(xiàn)unction對象的方法,每個函數(shù)都能調(diào)用;
使用apply或call方法,其運行的上下文指向第一個參數(shù),apply的第二個參數(shù)是一個參數(shù)數(shù)組,call的第二個及其以后的參數(shù)都是數(shù)組里面的元素。
apply和call的常用用法:
數(shù)組之間的追加;
例如:多維數(shù)字轉(zhuǎn)一維
let arr=[1,[7,8],[5,6]]; res=[].concat.apply([],arr)
擴充作用域擁有Math的min和max方法,獲取數(shù)組中的最大值和最小值;
let numbers = [5, 458 , 120 , -215 ];
let maxInNumbers = Math.max.apply(Math, numbers), //458
maxInNumbers = Math.max.call(Math,5, 458 , 120 , -215); //458
驗證是否是數(shù)組;
function isArray(obj){
return Object.prototype.toString.call(obj) === "[object Array]" ;
}
讓類數(shù)組擁有方法;
比如: arguments對象,獲取到的文檔節(jié)點等,并沒有數(shù)組的那些方法:
Array.prototype.slice.apply(argument);
//理論上來說這個比較快,直接在原型上查找slice方法
//但實際上比較慢
或者
[].slice.apply(arguments);
//理論上來說這個比較慢,因為要Array做一個實例化再查找slice方法
//實際上比較快,因為現(xiàn)在的各種自動化工具會把上一種方法轉(zhuǎn)換為這種,而第二種代碼比較簡潔,所以會比較快;
也是改變函數(shù)體內(nèi)this的指向,bind()是es5中的方法,bind會創(chuàng)建一個新函數(shù),稱為綁定函數(shù),當調(diào)用這個函數(shù)的時候,綁定函數(shù)會以創(chuàng)建它時傳入bind()方法的第一個參數(shù)作為this,傳入bind()方法的第二個及以后的參數(shù)加上綁定函數(shù)運行時本身的參數(shù)按照順序作為原函數(shù)的參數(shù)來調(diào)用原函數(shù);
例如:(后面的代碼皆取自張鑫旭大神的博客)
var button = document.getElementById("button"), text = document.getElementById("text"); button.onclick = function() { alert(this.id); // 彈出text }.bind(text);
但由于ie6~ie8不支持該方法,所以若想在這幾個瀏覽器中使用,我們就要模擬該方法,這也是面試常考的問題,模擬的代碼如下:
if (!function() {}.bind) { Function.prototype.bind = function(context) { var self = this; var args = Array.prototype.slice.call(arguments); return function() { return self.apply(context, args.slice(1)); } }; }
上面的代碼中this的指向是個容易理解錯的地方。
首先,我們判斷是否存在bind方法,然后,若不存在,向Function對象的原型中添加自定義的bind方法。
這里面var self = this這段代碼讓我很困擾,按理說,prototype是一個對象,對象的this應(yīng)該指向?qū)ο蟊旧恚簿褪莗rototype,但真的是這樣嗎。看看下面的代碼:
function a(){}; a.prototype.testThis = function(){console.log(a.prototype == this);}; var b = new a(); b.testThis();//false
顯然,this不指向prototype,而經(jīng)過測試,它也不指向a,而指向b。所以原型中的this值就明朗了。指向調(diào)用它的對象。
Array.prototype.slice.call(arguments);
上面這段代碼,它的作用是將一個類數(shù)組轉(zhuǎn)化為真正的數(shù)組,arguments是傳給call的那個上下文(由于arguments自己沒有slice方法,這里屬于借用Array原型的slice方法)。而且經(jīng)過測試,若果你不給slice傳參數(shù),那就等于傳了個0給它,結(jié)果就是返回一個和原來數(shù)組一模一樣的副本。
這之后的代碼就很好理解,返回一個函數(shù),該函數(shù)把傳給bind的第一個參數(shù)當做執(zhí)行上下文,由于args已經(jīng)是一個數(shù)組,排除第一項,將之后的部分作為第二部分參數(shù)傳給apply,前面講過apply的用法。
如此,我們自己的這個bind函數(shù)的行為就同es5中的bind一樣了。
總之三個的使用區(qū)別:
都是用來改變函數(shù)的this對象的指向的;
第一個參數(shù)都是this要指向的對象;
都可以利用后續(xù)參數(shù)傳參;
bind是返回對應(yīng)函數(shù),便于稍后調(diào)用,apply、call是立即調(diào)用;
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/102180.html
摘要:綁定函數(shù)被調(diào)用時,也接受預設(shè)的參數(shù)提供給原函數(shù)。一個綁定函數(shù)也能使用操作符創(chuàng)建對象這種行為就像把原函數(shù)當成構(gòu)造器。 一直很難理解js中的call apply bind,在w3schools,mdn閱讀了,也看了很多相關(guān)的文章,今天我來寫下我理解的call apply bind 首先創(chuàng)建一個函數(shù) function man(){} man.prototype = { name: ...
摘要:理解文章中已經(jīng)比較全面的分析了在中的指向問題,用一句話來總結(jié)就是的指向一定是在執(zhí)行時決定的,指向被調(diào)用函數(shù)的對象。與和直接執(zhí)行原函數(shù)不同的是,返回的是一個新函數(shù)。這個新函數(shù)包裹了原函數(shù),并且綁定了的指向為傳入的。 理解 JavaScript this 文章中已經(jīng)比較全面的分析了 this 在 JavaScript 中的指向問題,用一句話來總結(jié)就是:this 的指向一定是在執(zhí)行時決定的,...
摘要:它代表函數(shù)運行時,自動生成的一個內(nèi)部對象,只能在函數(shù)內(nèi)部使用類似的還有。總結(jié)關(guān)鍵字就是,誰調(diào)用我,我就指向誰。注意由于已經(jīng)被定義為函數(shù)內(nèi)的一個變量。因此通過關(guān)鍵字定義或者將聲明為一個形式參數(shù),都將導致原生的不會被創(chuàng)建。 題目 封裝函數(shù) f,使 f 的 this 指向指定的對象 。 輸入例子 bindThis(function(a, b) { return this.test +...
摘要:它們有明確的和成員函數(shù)的定義,只有的實例才能調(diào)用這個的成員函數(shù)。用和調(diào)用函數(shù)里用和來指定函數(shù)調(diào)用的,即指針的指向。同樣,對于一個后的函數(shù)使用或者,也無法改變它的執(zhí)行,原理和上面是一樣的。 函數(shù)里的this指針 要理解call,apply和bind,那得先知道JavaScript里的this指針。JavaScript里任何函數(shù)的執(zhí)行都有一個上下文(context),也就是JavaScri...
摘要:和區(qū)別其實他們的作用是一樣的,只是傳遞的參數(shù)不一樣而已。接受個參數(shù),第一個參數(shù)指定了函數(shù)體內(nèi)對象的指向,第二個參數(shù)為數(shù)組或者一個類數(shù)組。看個栗子一個有意思的事在中,多次是無效的。而則會立即執(zhí)行函數(shù)。 背景 前兩天在做小程序的需求的時候用到bind的時候才想起自己對這三的東西的了解比較淺薄,這個時候用的時候就有點怕。時候還是要好好學習下,理解下怎么玩。 正文 先說call 和 apply...
閱讀 2399·2021-11-24 10:26
閱讀 2587·2021-11-16 11:44
閱讀 1706·2021-09-22 15:26
閱讀 3586·2021-09-10 11:11
閱讀 3192·2021-09-07 10:25
閱讀 3632·2021-09-01 10:41
閱讀 1015·2021-08-27 13:11
閱讀 3514·2021-08-16 11:02