call、apply、bind实现原理

本文详细解析了JavaScript中this的概念及其在不同函数调用方式下(call、apply、bind)的行为。通过实例介绍了如何改变this的指向,并实现了call、apply和bind的模拟实现,帮助理解它们的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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')
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值