手动实现call、apply、bind

手动实现call、apply、bind

实现call

// 第一种方式
Function.prototype.myCall = function (context, ...args) {
  context = context || window;
  console.log("myCall", context);
  context._fn_ = this;// fn 只是个属性名 你可以随意起名,但是要注意可能会覆盖context上本来就有的属性
  let result = context._fn_(...args);
  delete context.fn;
  return result;
}

// 第二种方式
Function.prototype.myCall2 = function (context) {
  context = context || window;// context为null时 设为window
  let fn = Symbol();
  let args = [...arguments].slice(1);// 获取除context以外的所有参数
  context[fn] = this;// 确保了fn 属性的唯一性
  let result = context[fn](...args);
  delete context[fn];
  return result;
}
// 测试
let Person_Call = {
  name: "Tom",
  say: function (...args) {
    console.log(this)
    console.log(`我叫${this.name},我今年${args[0]},我的工作是${args[1]}`)
  }
}
let person1 = {
  name: "Jack"
}

Person_Call.say.myCall(person1, 19, "老师");// 我叫Jack,我今年19,我的工作是老师

实现call

// 实现apply
Function.prototype.myApply = function (context) {
  context = context || window;// context为null时 设为window
  let fn = Symbol();
  let args = [...arguments].slice(1);// 获取除context以外的所有参数
  context[fn] = this;// 确保了fn 属性的唯一性
  let result = context[fn](args); // 传入的为数组,就这点和call不同
  delete context[fn];
  return result;
}

// 测试用例 注意say函数中的参数为args不是...args
let Person_Apply = {
  name: "Tom",
  say: function (args) {
    console.log(this)
    console.log(`我叫${this.name},我今年${args[0]},我的工作是${args[1]}`)
  }
}
let person1 = {
  name: "Jack"
}
// 传入的是数组
Person_Apply.say.myApply(person1, [19, "医生"])// 我叫Jack,我今年19,我的工作是医生

实现bind

// 实现bind 
Function.prototype.myBind = function (context) {
  //返回一个绑定this的函数,我们需要在此保存this
  let self = this
  // 可以支持柯里化传参,保存参数(这里保存的是调用myBind方法时传来的参数)
  let arg = [...arguments].slice(1)
  // 返回一个函数
  return function () {
    //同样因为支持柯里化形式传参我们需要再次获取存储参数(这里保存的是调用myBind方法时返回的函数的参数)
    let newArg = [...arguments]
    console.log(newArg)
    // 返回函数绑定this,传入两次保存的参数
    //考虑返回函数有返回值做了return
    return self.apply(context, arg.concat(newArg));
}
// 测试用例
let Person_Bind = {
  name: "Tom",
  say: function (...args) {
    console.log(this)
    console.log(`我叫${this.name},我今年${args[0]},我的工作是${args[1]}`)
  }
}
let person1 = {
  name: "Jack"
} 
// 和call传入的参数一样都是一个一个的传入
var per = Person_Bind.say.myBind(person1, 20, "律师");
per();// 我叫Jack,我今年20,我的工作是律师
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值