js 手写实现call,apply,bind方法及它们区别

2020-06-07  本文已影响0人  沉默紀哖呮肯伱酔

首先我们先说一下这三个方法是干什么的?

function a(arg){
  console.log(this.name,"我的参数是" + arg)
}
const obj = {
  name:"我是对象"
}
a.call(obj,"call");      // 我是对象 我的参数是call
a.apply(obj,["apply"]); // 我是对象 我的参数是apply
a.bind(obj,"")();      // 我是对象 我的参数是bind

那么他们有什么区别呢?

接下来我们手写实现三个方法

call方法的实现:

Function.prototype.call(newThis,...arg){
    const newThis.fn = this;// 这样写有一个问题 那就是可能覆盖原有属性fn
    return newThis.fn(...arg)
}

Function.prototype.call(newThis = window,...arg){
    // 我们还需要给newThis 一个默认值,如果没有传递this 默认就是window
    const fn = Symbol('fn'); // 我们声明一个独一无二的属性
    return newThis[fn](...arg)
}

apply方法的实现:

apply方法的实现方法和call方法差不多,需要注意的就是参数传递的问题

Function.protptype.apply(newThis = window,arg){
    // 我们还需要给newThis 一个默认值,如果没有传递this 默认就是window
    const fn = Symbol('fn'); // 我们声明一个独一无二的属性
    return newThis[fn](...arg)
}

bind方法的实现:

Function.prototype.bind(newThis,...arg){
  const that = this;
  const newFunction = function (){
    const self =  this instanceof that ? this : thisArg;// 保证this的指向
    that.apply(self,arg.concat(Array.prototype.slice.call(arguments)));
    // newBind函数还可以接受参数,所以需要把newBind函数的参数和原函数的参数合并在一起
  }
  // 还需要继承原型上的属性和方法
  Function.prototype = Object.create(self.prototype);

  return newFunction
}
上一篇 下一篇

猜你喜欢

热点阅读