击剑JavaScript(一)

🤺JavaScript之 call | apply| bind 函数手写以及解释


话不多说上代码…希望多写博客可以让我收获更多OFFER

apply函数手写

Function.prototype.applyNew = function(context, args) {
  context.fn = this; //给context添加一个fn属性,这是一个方法,就是调用apply的函数
  console.log(context.fn);
  let res;
  if(!args) {
    context.fn();
  }
  else {
    res = context.fn(...args);
  }
  return res;
}

let obj = {
  name: 'jack'
}
function test(arg1, arg2, arg3) {
  console.log(this.name)   // jack
  console.log(arg1, arg2, arg3);  // 1 2 3
}
test.applyNew(obj, [1,2,3]);

我们这样理解,apply 函数就是让context 这个对象去使用调用apply这个函数的方法,这里是test。但是我们又需要访问到context这个对象里面的内容对不?所以怎么办——context里面添加一个属性,这个属性是一个方法而且就是这个函数test。所以我们在context 上添加了一个属性fn,然后这个属性就是函数test,也就是this。因为this就是调用这个函数的上下文。

bind函数手写

Function.prototype.bindNew = function(context, ...args) {
  return (...newArgs) => {
    this.apply(context,[...args, ...newArgs])
  }
}

const test = {
  name: "fy",
  showName: function (last) {
    console.log(this.name + " is " + last);
  },
};
test.showName("handsome"); // fy is handsome
test.showName.bind({ name: "Mr.fy" })("handsome");
test.showName.bindNew({ name: "Mr.fy" })("hello");

好像没什么要说的…但是我在写的时候发现return不能写一个function而只可以写箭头函数,因为我们后面其实是使用apply去做到改变this指向并且执行函数,那么只有使用了箭头函数才可以捕获上下文,只使用function是不能明确上下文的。但是也可以人为获取上下文比如:

Function.prototype.bindNew = function(context, ...args) {
  let self = this;
  return function(...newArgs) {
    self.apply(context,[...args, ...newArgs])
  }
}

const test = {
  name: "fy",
  showName: function (last) {
    console.log(this.name + " is " + last);
  },
};
test.showName("handsome"); // fy is handsome
test.showName.bind({ name: "Mr.fy" })("handsome");
test.showName.bindNew({ name: "Mr.fy" })("hello");

这里面首先使用self去获取上下文this,然后后面直接使用self就可以(为什么我更喜欢这种,我感觉这种更清晰更易懂)

call函数手写

Function.prototype.callNew = function(context,...args) {
  context.fn = this;
  var res = context.fn(...args);
  delete context.fn;
  return res;
}

let obj = {
  name: 'jack'
}
function test(arg1, arg2, arg3) {
  console.log(this.name)   // jack
  console.log(arg1, arg2, arg3);  // 1 2 3
}
test.callNew(obj, 1,2,3);

其实callapply很像了,就是参数必须一个一个传,那这样我们就是用...拓展符就好了。但是要记删除context.fn,因为,不仅仅是为了释放内存,而且我们使用这些函数的目的就是做到改变上下文,那又为啥要改变人家对象的属性给人家添油加醋(虽然我很喜欢hhhh)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值