【JS】call、apply和bind函数以及手写实现

文章详细介绍了JavaScript中用于改变函数内部this指针的call(),apply()和bind()方法,包括它们的使用方式、区别以及如何手写这三个方法的实现。通过示例展示了如何在不同场景下设置函数的上下文和参数。

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

一、call()

  1. 语法:通过call()调用函数,fn.call(obj,...args)
  2. 调用函数的时候,可以设置obj,改变this指向
  3. 如果obj是null或undefined,this指向window
  4. 后面的参数是若干个,数量是可变的
function func(a, b) {
  console.log('func', this, a, b);
}

// 调用func函数
func(); //window undefined undefined
// call()
func.call([1, 2, 3], 122, 33); //[ 1, 2, 3 ] 122 33

// 匿名函数使用call()
(function () {
  console.log(this);  //100
}).call(100)

var obj = {
  name: 'obj',
  getInfo: function () {
    console.log(this);
  }
}
obj.getInfo()   //obj
obj.getInfo.call('hello') // hello

二、apply()

  1. 通过apply()调用函数
  2. 调用函数的时候,可以设置函数内部的this
  3. 除了this只有一个参数,并且是数组,其中的数组元素将作为单独的参数传给fun函数。和call()唯一的区别
function func(a, b) {
  console.log('func', this, a, b);
}

func.apply({ name: 'xxx' }, [12, 'ss']) //{ name: 'xxx' } 12 ss

三、bind()

  1. 返回一个新的函数,需要手动调用
  2. bind创建时设置this,也可以设置一个固定参数
  3. 调用新函数时,设置参数
function func(a, b) {
  console.log('func', this, a, b);
}

var fn1 = func.bind([2, 3])
fn1('q', 'w');      //[ 2, 3 ] q w

var user = { name: 'xxx' }
user.getInfo = func.bind(100, 'qwe');
user.getInfo()    //100 qwe undefined

四、手写call、apply、bind函数

function myCall(fn, thisarg, ...args) {
  // 如果传入的是null或undefined,this指向window
  if (thisarg == null || thisarg == undefined) {
    return fn(...args)
  }

  // 给obj添加方法:属性名随意,属性值必须当前调用call的函数对象
  thisarg.tempFn = fn
  const result = thisarg.tempFn(...args)
  delete thisarg.tempFn
  return result
}

function myApply(fn, thisarg, args) {
  // 如果传入的是null或undefined,this指向window
  if (thisarg == null || thisarg == undefined) {
    return fn(args)
  }

  // 给obj添加方法
  thisarg.tempFn = fn
  let result
  // 如果参数不存在直接调用;参数存在传参调用
  if (!args) {
    result = thisarg.tempFn()
  } else {
    result = thisarg.tempFn(...args)
  }
  delete thisarg.tempFn
  return result
}

function myBind(fn, thisarg, ...args) {
  // // 如果传入的是null或undefined,this指向window
  // if (thisarg == null || thisarg == undefined) {
  //   return fn(args)
  // }
  // // 给obj添加方法
  // thisarg.tempFn = fn
  // return function (...args2) {
  //   const result = thisarg.tempFn(...args, ...args2)
  //   delete thisarg.tempFn
  //   return result
  // }
  return function (...args2) {
    return myCall(fn, thisarg, ...args, ...args2)
  }
}

// 验证
function func(a, b) {
  console.log(this, a, b);
}
myCall(func, [1, 2])
myApply(func, [1, 2])
let res = myBind(func, [1, 2], 'w')
console.log(res(1));
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值