call、apply、bind实现原理

this的概念

  1. this是作用域中的参数
  2. 解析器在每次调用函数的时候都会向函数内部传递进一个隐含的参数,这个隐含的参数就是this;
  3. this指向的是一个对象,函数执行的上下文对象;
  4. 根据函数的调用方式的不同,this会指向不同的对象

call实现原理

  1. call会立即执行函数
  2. 所谓的改变this,就是把需要改变this的函数挂载到context对象的临时fn
  3. 然后调用context里边的临时fn,这样就会把this指向context
  4. 为了保证不改变原来的对象,最后需要删除临时fn
	Function.prototype.newCall = function (context,...arg) {
		const ctx = context || window; // 没传或者传null默认是window
	    ctx.fn = this // 将call方法的目标函数挂到目标对象身上
	    const res = ctx.fn(...args)// 执行fn并传参,这时候this已经执行context了,因为fn是contex调用的
	    delete context.fn // 删除fn,不污染原对象
	    return res
   }
	function test(name) {
	    console.log(name + this.age + '岁了');
	}
	const obj = { age: 23 }
	test.newCall(obj, 'sea')// sea23岁了

apply实现原理

与call的实现原理相同,就是传参的方式略微不同。传的是一个数组。

	Function.prototype.newApply = function (context, arr=[]) {
        const ctx = context || window;
	    ctx.fn = this // 将apply方法的目标函数挂到目标对象身上
	    const res = ctx.fn(arr)
	    delete context.fn
	    return res
    }

bind实现原理

  1. bind不会立即执行函数,所以需要返回一个待执行的函数从而产生闭包
  2. 参数传递,由于参数的不确定性,用数组更好
Function.prototype.myBind = function (context, ...arg) {
    const ctx = context || window;
    ctx.fn = this; // 重要! this就是当前执行的函数. 给对象添加一个函数,那么这个函数内部的this就指向这个对象了
    return function () {
      const res = ctx.fn(...arg,...arguments); // 执行这个函数
      delete ctx.fn;
      return res;
    };
  };
  
  var test = function(a,b){
      console.log('作用域绑定 '+ this.value)
      console.log('testBind参数传递 '+ a.value2)
      console.log('调用参数传递 ' + b)
  }
  var obj = {value:'ok'}
  var newFn = test.myBind(obj,{value2:'also ok'})
   
  newFn ('hello bind')
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
call、applybind都是用来改变函数中的this指向的方法。其中,call和apply可以直接调用函数并传递参数,而bind则返回一个新的函数,需要手动调用。 具体实现方案如下: - call的实现: 1. 给想要绑定的对象设置一个属性,并将该属性指向需要调用的函数。 2. 使用该对象调用函数,并传递参数。 3. 结束调用后,删除该属性。 - apply的实现: 1. 给想要绑定的对象设置一个属性,并将该属性指向需要调用的函数。 2. 使用该对象调用函数,并传递参数数组。 3. 结束调用后,删除该属性。 - bind的实现: 1. 创建一个新的函数,并将原函数作为其中的属性保存起来。 2. 当新函数被调用时,将之前绑定的对象作为this,并传递参数。 3. 返回新函数供后续调用。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [如何实现call、applybind](https://blog.csdn.net/XIAO_A_fighting/article/details/116701887)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [原生JS实现 call apply bind](https://download.csdn.net/download/weixin_38628990/14046564)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值