手写call,apply,bind方法

call

Function.prototype.myCall = function (obj = window) { // 不传参默认为window
  obj.fn = this
  const args = [...arguments].slice(1)
  const res = obj.fn(...args)
  delete obj.fn
  return res
}


var obj = {
  x: 10
}
function foo() {
  console.log(this);  // { x: 10, fn: [Function: foo] }
  console.log(this.x);  // 10
}
foo.myCall(obj);

代码解析:

var obj = {
  x: 10
}

Function.prototype.myCall = function (context = window) {
  context.fn = this // this指向实例,此例为foo
  // console.log(this); // [Function: foo]
  // console.log(context); // { x: 10, fn: [Function: foo] }
  const args = [...arguments].slice(1) // 去掉第一个参数,就是context,这里就是obj
  // console.log(args); // [1,2]
  const result = context.fn(...args)
  delete context.fn // 删除方法属性fn
  return result
}

function foo(a, b) {
  console.log(this) // { x: 10, fn: [Function: foo] }
  console.log(a + b) // 3
}
foo.myCall(obj, 1, 2);

apply和call实现类似,不同的就是参数的处理:

Function.prototype.myApply = function (obj = window) {
  obj.fn = this
  let result
  if (arguments[1]) {
    result = obj.fn(...arguments[1])
  } else {
    result = obj.fn()
  }
  delete obj.fn
  return result
}

var obj = {
  x: 10
}
function foo() {
  console.log(this);  // { x: 10, fn: [Function: foo] }
  console.log(this.x);  // 10
}
foo.myApply(obj);

代码解析:

var obj = {
  x: 1
}

Function.prototype.myApply = function (obj = window) {
  obj.fn = this
  let res
  if (arguments[1]) {
    res = obj.fn(...arguments[1])
  } else {
    res = obj.fn()
  }
  delete obj.fn
  return res
}

function f1(a, b) {
  console.log(this);
  console.log(this.x);
  console.log(a + b);
}

f1.myApply(obj, [1, 2])

bind

Function.prototype.mybind = function (context = window) { // 原型上添加mybind方法
  var argumentsArr = Array.prototype.slice.call(arguments) // 类数组转数组
  var args = argumentsArr.slice(1) // 后面的参数
  var self = this // 调用的方法本身
  return function () { // 返回一个待执行的方法
    var newArgs = Array.prototype.slice.call(arguments) // 返回函数的arguments
    self.apply(context, args.concat(newArgs)) // 合并两args
  }
}

var obj = {
  x: 10
}
function foo() {
  console.log(this);  // {x: 10}
  console.log(this.x);  // 10
}
foo.mybind(obj)();

代码解析:

var obj = {
  x: 10
}

Function.prototype.myBind = function (obj = window) {
  obj.fn = this // this指向实例,此例为foo
  const res = function () { // 包裹在一个函数里面
    obj.fn(...arguments)
    delete obj.fn // 删除方法属性fn
  }
  return res
}

function foo(a, b) {
  console.log(this) // { x: 10, fn: [Function: foo] }
  console.log(a + b)
}
foo.myBind(obj)(1, 2)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

敲起来blingbling

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

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

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

打赏作者

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

抵扣说明:

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

余额充值