JS之手写 call apply

364 阅读1分钟

call 实现

我们知道,call 和 apply 的核心就是改变函数内部 this 的指向

// 以下的 call 和 apply 均指自己实现的函数

那么思路就是让 call 的第一个参数去调用调用 call 的函数,听起来是不是很绕,让我们来实现一下

Function.prototype.call2=function(context){
    context=context ? Object(context) : window
    let fn = Symbol()  
    context[fn] = this
    let args = [...arguments].slice(1)
    let result = context[fn](...args)
    delete context[fn]
    return result
}

使用 Symbol 是为了和本身属性不冲突

一开始我有一个愚蠢的疑问,既然 fn 这个属性刚被创建马上又被删除,那么我为什么不直接让 this(也就是调用 call 的函数) 去执行呢?

简直是愧为前端哈哈哈,因为如果按照上述做法执行,call 前面的函数在执行时内部的 this 是 window,违背了我们的初衷

我们应该让 context 对象自己去调用函数,这样函数内部的 this 才是 context 对象,注意使用完删除此属性

apply 实现

apply 实现方法和 call 非常类似,代码如下:

Function.prototype.apply2 = function(context,arr){
    context = context ? Object(context) : window
    let fn = Symbol()
    context[fn] = this
    let result = arr ? context[fn](...arr) : context[fn]()
    delete context[fn]
    return result
}