前端面试call()、apple()、bind() 方法的手写实现记录(常见方法的实现)

认识call、apple、bind 三者

  • 功能:用来改变 this 的指向
  • call() 与 apple() 类似,不同的是call包含多个参数: call(thisObj, 1 , 2, 3 …);而apple的参数是一个数组:apple(thisObj, [1, 2, 3 …])。
  • call、apple、bind的区别:call、apple 是调用后立即返回结果;bind是返回一个函数

myCall() 方法的实现

看下面一段原生call方法

var obj1 = {
  name: '假装文艺浪',
  hobby: '打篮球',
  fn: function () {
    console.log('爱好', this.hobby)
  }
}
let obj = {
  hobby: '敲代码'
}

obj1.fn()
obj1.fn.call(obj)

// 爱好 打篮球
// 爱好 敲代码

当我们使用call方法时,打印的是 “敲代码” 而不是 “打篮球”,this指向了 obj 对象中的 hobby,即改变了this的指向
接下来实现我们自己的call()方法

Function.prototype.myCall = function(context = window, ...args) {
  if (typeof this !== 'function') {
    throw new TypeError('Type Error')
  }
  // Symbol 独一无二 ES6
  const fn = Symbol('fn')
  context[fn] = this
  const res = context[fn](...args)
  delete context[fn]
  return res
}

obj1.fn()
obj1.fn.myCall(obj)

// 爱好 打篮球
// 爱好 敲代码

查看打印结果,与原生call方法无异

apple()方法的实现

原生的apple

var obj1 = {
  name: '假装文艺浪',
  hobby: '打篮球',
  fn: function (x, y) {
    console.log('爱好',this.hobby)
    console.log(x + y)
  }
}
let obj = {
  hobby: '敲代码'
}

obj1.fn(2,3)
obj1.fn.apply(obj,[1,2])
// 爱好 打篮球
// 5
// 爱好 敲代码
// 3

call与apple的不同就是参数的形式,我们的apple() 方法的实现

Function.prototype.myApple = function(context = window, args) {
  if (typeof this !== 'function') {
    throw new TypeError('Type Error')
  }
  const fn = Symbol('fn')
  context[fn] = this
  const res = context[fn](...args)
  delete context[fn]
  return res
}

obj1.fn(2,3)
obj1.fn.myApple(obj,[1,2])
// 爱好 打篮球
// 5
// 爱好 敲代码
// 3

bind()方法的实现

原生的bind()方法

function fn (x,y) {
  console.log(this.hobby)
  console.log(x + y)
}
let obj = {
  hobby: '敲代码'
}

fn(2,3)
console.log(typeof fn.bind(obj,1,2))
fn.bind(obj,1,2)()
// undefined
// 5
// function
// 敲代码
// 3

通过打印的结果可以看出,bind()方法返回的是一个函数,而不是执行结果
this指向了obj对象

下面实现我们的bind()方法,

Function.prototype.myBind = function(context, ...args) {
  // 判断是否为函数
  if (typeof this !== 'function') {
    throw new Error("Type Error");
  }
  // 保存this的值,指向函数
  var self = this;

  return function F() {
    // 考虑new的情况
    if(this instanceof F) {
      return new self(...args, ...arguments)
    }
    // 调用apply,改变this执行
    return self.apply(context, [...args, ...arguments])
  }
}
fn(2,3)
console.log(typeof fn.myBind(obj,1,2))
fn.myBind(obj,1,2)()
// undefined
// 5
// function
// 敲代码
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值