手写call,apply,bind[手写代码]

在JavaScript中,callapplybind都是用来改变函数执行上下文的方法,它们都能够显式地指定函数运行时的 this 值。

call

call 方法用于调用一个函数,其语法如下:

fun.call(thisArg, arg1, arg2, ...)
  • fun: 要调用的函数。
  • thisArg: 被调用时作为 this 的对象。
  • arg1, arg2, …: 函数调用时传递的参数。

call 方法会将 thisArg 指定为函数的执行上下文,也就是函数内部的 this 值。可以通过传递额外的参数来调用函数。
示例:

const obj = {
  name: 'Alice',
  sayHello() {
    console.log(`Hello, ${this.name}!`)
  }
}
const obj2 = {
  name: 'Bob'
}
obj.sayHello() // Hello, Alice!
obj.sayHello.call(obj2) // Hello, Bob!
call手写模拟
Function.prototype.myCall = function (context,...args) {
//注意:context是要绑定的指向;this是调用myCall的函数;
//也就是将this的this指向context
  let result = null;
  // 判断 context 是否传入,如果没有传就设置为 window
  context = context || window;
  context.fn = this;
  // 执行要被调用的方法
  result = context.fn(...args);
  // 删除手动增加的属性方法
  delete context.fn;
  // 将执行结果返回
  return result;
};

apply

apply 方法与 call 方法类似,它也是用来调用函数并指定函数执行上下文的,但是它传递参数的方式不同,它的语法如下:

fun.apply(thisArg, [argsArray])
  • fun: 要调用的函数。
  • thisArg: 被调用时作为 this 的对象。
  • argsArray: 一个数组或类数组对象,其中的元素将作为单独的参数传递给函数。

apply 方法会将 thisArg 指定为函数的执行上下文,并将 argsArray 数组中的元素作为函数调用时的参数。

示例:

const numbers = [5, 6, 2, 3, 7]
const maxNumber = Math.max.apply(null, numbers)
console.log(maxNumber) // 7
apply手写模拟
Function.prototype.myApply = function (context,args) {
//注意:context是要绑定的指向;this是调用myApply的函数;
//也就是将this的this指向context
  let result = null;
  // 判断 context 是否传入,如果没有传就设置为 window
  context = context || window;
  context.fn = this;
  // 执行要被调用的方法
  result = context.fn(...args);
  // 删除手动增加的属性方法
  delete context.fn;
  // 将执行结果返回
  return result;
};

bind

bind 方法与 callapply 方法有所不同,它不是立即调用函数,而是创建一个新的函数,并将 this 值绑定到指定的对象上。它的语法如下:

fun.bind(thisArg, arg1, arg2, ...)
  • fun: 要绑定 this 的函数。
  • thisArg: 被绑定时作为 this 的对象。
  • arg1, arg2, …: 被绑定时传递给函数的参数。

bind 方法不会立即执行函数,而是返回一个新的函数,这个新的函数的 this 值被永久绑定在 thisArg 对象上。绑定后的函数可以像原函数一样被调用,并且可以传递参数。注意,当调用绑定函数时,会将绑定函数中的参数和传递的参数合并,传递给原函数。

function greeting() {
  console.log('Hello, ' + this.name + '!')
}
const person = {
  name: 'John'
}
const greet = greeting.bind(person)
greet() // 输出:Hello, John!

在上面的例子中,bind()方法将person对象绑定到greeting()函数的this关键字上,并返回一个新的函数greet()。调用greet()函数时,执行该函数并输出Hello, John!。注意,bind()方法并不会立即执行函数,而是返回一个新的函数。

bind手写
Function.prototype.myBind = function (context,...args) {
//注意:this是调用myBind的函数,context是期望绑定的指向
//也就是绑定this的this指向context

let that = this
  //返回一个函数
  return function Fn() {
    //这个被返回的函数一旦被调用,则调用真正的函数,并绑定其this指向
    let result = null
    context = context || window;
    //这个函数中的this指向Fn()的调用者
    //所以,要用that拿到myBind的this
    context.fn = that;
    result = context.fn(...args);
    //鲁棒: result = context.fn(...[...args,...arguments]);
    delete context.fn;
    return result;
  };
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学不会只能哭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值