摘要:簡單說一下的區(qū)別三者都是用于改變函數(shù)體內(nèi)的指向,但是與和的最大的區(qū)別是不會(huì)立即調(diào)用,而是返回一個(gè)新函數(shù),稱為綁定函數(shù),其內(nèi)的指向?yàn)閯?chuàng)建它時(shí)傳入的第一個(gè)參數(shù),而傳入的第二個(gè)及以后的參數(shù)作為原函數(shù)的參數(shù)來調(diào)用原函數(shù)。原文鏈接的區(qū)別與實(shí)現(xiàn)原理
1、簡單說一下bind、call、apply的區(qū)別
三者都是用于改變函數(shù)體內(nèi)this的指向,但是bind與apply和call的最大的區(qū)別是:bind不會(huì)立即調(diào)用,而是返回一個(gè)新函數(shù),稱為綁定函數(shù),其內(nèi)的this指向?yàn)閯?chuàng)建它時(shí)傳入bind的第一個(gè)參數(shù),而傳入bind的第二個(gè)及以后的參數(shù)作為原函數(shù)的參數(shù)來調(diào)用原函數(shù)。
var obj = {}; function test() { console.log(this === obj); } test(); //false var testObj = test.bind(obj); testObj(); //true
apply和call都是為了改變某個(gè)函數(shù)運(yùn)行時(shí)的上下文而存在的(就是為了改變函數(shù)內(nèi)部this的指向);apply和call的調(diào)用返回函數(shù)執(zhí)行結(jié)果;
如果使用apply或call方法,那么this指向他們的第一個(gè)參數(shù),apply的第二個(gè)參數(shù)是一個(gè)參數(shù)數(shù)組,call的第二個(gè)及其以后的參數(shù)都是數(shù)組里面的元素,就是說要全部列舉出來;
以下是MDN文檔:
bind語法: func.bind(thisArg[, arg1[, arg2[, ...]]]) thisArg 當(dāng)綁定函數(shù)被調(diào)用時(shí),該參數(shù)會(huì)作為原函數(shù)運(yùn)行時(shí)的this指向。當(dāng)使用new 操作符調(diào)用綁定函數(shù)時(shí),該參數(shù)無效。 arg1, arg2, ... 當(dāng)綁定函數(shù)被調(diào)用時(shí),這些參數(shù)將置于實(shí)參之前傳遞給被綁定的方法。
call語法: fun.call(thisArg, arg1, arg2, ...) thisArg::在fun函數(shù)運(yùn)行時(shí)指定的this值。需要注意的是,指定的this值并不一定是該函數(shù)執(zhí)行時(shí)真正的this值,如果這個(gè)函數(shù)處于非嚴(yán)格模式下,則指定為null和undefined的this值會(huì)自動(dòng)指向全局對象(瀏覽器中就是window對象),同時(shí)值為原始值(數(shù)字,字符串,布爾值)的this會(huì)指向該原始值的自動(dòng)包裝對象。 arg1, arg2, ... 指定的參數(shù)列表。
apply語法: fun.apply(thisArg, [argsArray]) thisArg: 在 fun 函數(shù)運(yùn)行時(shí)指定的 this 值。需要注意的是,指定的 this 值并不一定是該函數(shù)執(zhí)行時(shí)真正的 this 值,如果這個(gè)函數(shù)處于非嚴(yán)格模式下,則指定為 null 或 undefined 時(shí)會(huì)自動(dòng)指向全局對象(瀏覽器中就是window對象),同時(shí)值為原始值(數(shù)字,字符串,布爾值)的 this 會(huì)指向該原始值的自動(dòng)包裝對象。 argsArray: 一個(gè)數(shù)組或者類數(shù)組對象,其中的數(shù)組元素將作為多帶帶的參數(shù)傳給 fun 函數(shù)。如果該參數(shù)的值為null 或 undefined,則表示不需要傳入任何參數(shù)。從ECMAScript 5 開始可以使用類數(shù)組對象。
區(qū)別總結(jié):
當(dāng)我們使用一個(gè)函數(shù)需要改變this指向的時(shí)候才會(huì)用到call,apply,bind
如果你要傳遞的參數(shù)不多,則可以使用fn.call(thisObj, arg1, arg2 ...)
如果你要傳遞的參數(shù)很多,則可以用數(shù)組將參數(shù)整理好調(diào)用fn.apply(thisObj, [arg1, arg2 ...])
如果你想生成一個(gè)新的函數(shù)長期綁定某個(gè)函數(shù)給某個(gè)對象使用,則可以使用
const newFn = fn.bind(thisObj); newFn(arg1, arg2...)2、bind、call、apply的實(shí)現(xiàn) myBind:
Function.prototype.myBind = function() { var _this = this; var context = [].shift.call(arguments);// 保存需要綁定的this上下文 var args = [].slice.call(arguments); //剩下參數(shù)轉(zhuǎn)為數(shù)組 console.log(_this, context, args); return function() { return _this.apply(context, [].concat.call(args, [].slice.call(arguments))); } };myCall:
/** * 每個(gè)函數(shù)都可以調(diào)用call方法,來改變當(dāng)前這個(gè)函數(shù)執(zhí)行的this關(guān)鍵字,并且支持傳入?yún)?shù) */ Function.prototype.myCall = function(context) { //第一個(gè)參數(shù)為調(diào)用call方法的函數(shù)中的this指向 var context = context || global; //將this賦給context的fn屬性 context.fn = this;//此處this是指調(diào)用myCall的function var arr = []; for (var i=0,len=arguments.length;imyApply: /** * apply函數(shù)傳入的是this指向和參數(shù)數(shù)組 */ Function.prototype.myApply = function(context, arr) { var context = context || global; context.fn = this; var result; if (!arr) { result = context.fn(); //直接執(zhí)行 } else { var args = []; for (var i=0,len=arr.length;i以上是bind、apply、和call的模擬實(shí)現(xiàn)
注意:綁定函數(shù)(bind函數(shù)返回的新函數(shù))不可以再通過apply和call改變其this指向,即當(dāng)綁定函數(shù)調(diào)用apply和call改變其this指向時(shí),并不能達(dá)到預(yù)期效果。var obj = {}; function test() { console.log(this === obj); } var testObj = test.bind(obj); testObj(); //true var objTest = { "作者": "chengbo" }; /** * 預(yù)期返回false, 但是testObj是個(gè)綁定函數(shù),所以不能改變其this指向 */ testObj.apply(objTest); //true testObj.call(objTest); //true歡迎留言。
原文鏈接:《bind、call、apply的區(qū)別與實(shí)現(xiàn)原理》
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/98420.html
摘要:理解文章中已經(jīng)比較全面的分析了在中的指向問題,用一句話來總結(jié)就是的指向一定是在執(zhí)行時(shí)決定的,指向被調(diào)用函數(shù)的對象。與和直接執(zhí)行原函數(shù)不同的是,返回的是一個(gè)新函數(shù)。這個(gè)新函數(shù)包裹了原函數(shù),并且綁定了的指向?yàn)閭魅氲摹? 理解 JavaScript this 文章中已經(jīng)比較全面的分析了 this 在 JavaScript 中的指向問題,用一句話來總結(jié)就是:this 的指向一定是在執(zhí)行時(shí)決定的,...
摘要:的調(diào)用者,將會(huì)指向這個(gè)對象。此外,還可以擴(kuò)展自己的其他方法。的使用最后來說說。不同的是,方法的返回值是函數(shù),并且需要稍后調(diào)用,才會(huì)執(zhí)行。而和則是立即調(diào)用。總結(jié)和的主要作用,是改變對象的執(zhí)行上下文,并且是立即執(zhí)行的。 前言 上一篇文章 《「前端面試題系列4」this 的原理以及用法》 中,提到了 call 和 apply。 它們最主要的作用,是改變 this 的指向。在平時(shí)的工作中,除了...
摘要:前言實(shí)踐系列主要是讓我們通過實(shí)踐去加深對一些原理的理解。求求三兄弟的作用都是為了改變函數(shù)運(yùn)行時(shí)上下文指向而存在的。不會(huì)立即調(diào)用其他兩個(gè)會(huì)立即調(diào)用。如果有幫助到你請給我一個(gè)就算是對我的感謝啦 前言 [實(shí)踐系列] 主要是讓我們通過實(shí)踐去加深對一些原理的理解。 實(shí)踐系列-前端路由 實(shí)踐系列-Babel原理 實(shí)踐系列-Promises/A+規(guī)范 實(shí)踐系列-瀏覽器緩存機(jī)制 有興...
摘要:請解釋事件代理事件代理也稱為事件委托,利用了事件冒泡。同源指的是協(xié)議域名端口相同,同源策略是一種安全協(xié)議。目的同源策略保證了用戶的信息安全,瀏覽器打開多個(gè)站點(diǎn)時(shí),互相之間不能利用獲取對方站點(diǎn)的敏感信息。 請解釋事件代理(event delegation) 事件代理也稱為事件委托,利用了事件冒泡。例如: item1 item2 item3 當(dāng)頁面li增多時(shí)單...
摘要:的原型上存放著實(shí)例的一些共有方法。每個(gè)函數(shù)都可以調(diào)用方法,來改變當(dāng)前這個(gè)函數(shù)執(zhí)行的關(guān)鍵字,并且支持傳入?yún)?shù)我們用原生模擬方法,來更加深刻了解它。和方法類似,作用都是改變當(dāng)前函數(shù)執(zhí)行的指向,并且將函數(shù)執(zhí)行。 Function的prototype原型上存放著 Function實(shí)例 的一些共有方法。A.Function的原型不像其他類(Array、Object...)的原型一樣是個(gè)對象,F(xiàn)u...
閱讀 2288·2021-11-16 11:51
閱讀 3508·2021-09-26 10:14
閱讀 1831·2021-09-22 15:58
閱讀 1100·2019-08-30 15:52
閱讀 2017·2019-08-30 15:43
閱讀 2619·2019-08-30 13:46
閱讀 913·2019-08-30 13:10
閱讀 1024·2019-08-29 18:32