手写一个call函数

191 阅读1分钟

call、apply、bind的作用:改变函数运行时上下文(this指向): 1、三个函数接收的第一个参数都是要绑定的this指向; 2、apply的第二个参数是一个参数数组,call和bind的第二个及之后的参数作为函数实参按顺序传入。 3、bind不会立即调用,其他两个会立即调用。

那么,为什么我们需要这三个函数呢? 假设现在有个对象:obj={ name:123 } 有个方法sayName(){ console.log(this.name) } 我们现在需要让obj对象调用sayName方法而又不想让obj拥有sayName方法,那么可以使用上述三个方法sayName.call(obj)

下面是手写的call方法,不太严谨,仅供参考:

Function.prototype.call = function (ctx){
    const cxt = ctx || window
    //让ctx对象临时拥有调用bind方法的函数:以上述sayName.apply(obj)为例,this会指向调用bind函数的方法(sayName),因此暂时让ctx对  象拥有sayName方法,func名字可能会跟ctx对象内属性产生冲突,此方法不考虑这种情况
    cxt.func = this
    const args = Array.from(arguments).slice(1)
    const res = arguments.length > 1 ? cxt.func(args):cxt.func()
    //删除被临时加到ctx内的调用bind方法的函数
    delete cxt.func
    return res
}