JavaScript 实现 call、apply和 bind

原生JavaScript实现call、apply和bind - Web前端工程师面试题讲解

给函数指定 this 值

具体实现是 apply, call 第一个参数会接受一个上下文的环境, 给这个上下文的环境添加一个你需要调用的函数 调用它并返回调用后的结果, 之后删除你之前添加的方法

apply 传入一个数组, 而 call 传入的是一个一个的参数

bind函数会返回一个新函数, 并且这个新函数的上下文环境改变了

并且在使用 bind 的时候, 可以在创建的时候传入参数, 还可以在调用的使用传入参数

具体实现的时候需要考虑 这个新函数是 直接调用 还是使用 new 的方式调用, 不同方式会有不同返回值

使用

let o = { 
  x: "some strings" ,
  haha(){
    console.log("haha");
  }
}

function f(a1, a2) {
  this.haha()
  console.log(this.x, a1, a2);
}

f.call(o, 1, 2)
f.apply(o, [1, 2])
let o2 = f.bind(o1)		// 此时的 o2 相当于 o1 对象中的 f() 函数
o2(1, 2)	
// haha
// some strings 1 2

apply实现

Function.prototype.myApply = function (context, arr) {
  // 可以不传
  context = context || {}
  arr = arr || []
  // this 代表调用的函数
  context.callback = this
  const res = context.callback(...arr)
  delete context.callback
  return res
}

let a = function (a, b, c, d) {
  console.log(this.name)    // 123
  console.log(a, b, c, d)   // 1 2 3 4
  return {
    a, b, c, d, name: this.name
  }
}
let qw = a.myApply({ name: 123 }, [1, 2, 3, 4])
let qq = a.apply({ name: 123 }, [1, 2, 3, 4])
console.log(qw)
console.log(qq)

call 实现

Function.prototype.myCall = function (context, ...args) {
  var context = context || {}
  context.callback = this
  const res = context.callback(...args)
  delete context.callback
  return res
}

let a = function (a, b, c, d) {
  console.log(this.name)    // zzz
  console.log(a, b, c, d)   // 1 2 3 4
  return {
    a, b, c, d, name: this.name
  }
}

let qq = a.myCall({ name: 'zy' }, 1, 2, 3, 4)
let qw = a.call({ name: 'zy' }, 1, 2, 3, 4)
console.log(qq)
console.log(qw)

bind

let a = function (a, b, c, d) {
  console.log(this.name)    // zy
  console.log(a, b, c, d)   // 1 2 3 4
  return 123
}

Function.prototype.myBind = function (context) {
  if (typeof this !== 'function') throw new Error('error')
  const args = [...arguments].slice(1), f = this
  return function F() {
    return f.apply(this instanceof F ? this : context, args.concat(...arguments))
  }
}

let qq = a.myBind({ name: 'zy' }, 1, 2)
let qw = qq(3, 4)
console.log(qw)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值