随手刷题——02.实现一个简单的Function.prototype.call/apply

257 阅读3分钟

定义

在JavaScript中,call是 Function 对象的一个方法,它的作用是在特定的作用域中调用函数,可以改变函数执行时的上下文(即 this 指向)。

call方法接收一个参数列表,在调用函数时将参数按照顺序传递给函数。第一个参数指定了函数运行时的 this 指向,如果第一个参数是 null 或 undefined,则 this 指向全局对象(在浏览器中为 window 对象)。

call方法与apply方法非常类似,它们都可以改变函数执行时的上下文,不同之处在于传入参数的方式不同。apply() 方法接受一个参数数组,而call方法接受一系列单独的参数。

作用

一个常见的应用场景是通过callapply方法,将一个对象的方法绑定到另一个对象上,从而实现方法的共享。此外,它还可以用于函数的借用、实现继承等方面。

初步实现

根据call方法的定义,我们可以得到以下的初步代码实现:

image.png

一些边界处理

但是,仅仅这样实现的call方法实现是非常基础的,没有进行参数类型校验和异常捕获处理。因此,在使用自己实现的call方法时需要注意一些细节,确保代码的正确性。

  1. 第一个参数必须传入一个对象,否则在执行this的时候会报错。
  2. 如果传入的第一个参数为null或undefined,this不再指向它们,而是默认为全局对象。
  3. 调用call方法的对象必须是一个函数,否则在执行myCall方法时会报错。
  4. 调用的函数可能存在副作用,需要在调用之前对参数进行备份,避免直接影响到原对象。

对于这些需要补充的地方,可以进行异常捕获处理,确保代码的可靠性。同时,也可以在函数的调用前进行相关参数的判断和处理,以避免出现错误情况。

image.png

测试用例

可以使用以下测试用例进行测试,可以发现,即使是异步函数调用了myCall,也可以正常返回结果。

image.png

总结

在手动实现一个 call 方法时,需要注意以下几个问题:

  1. call 是函数原型上的一个方法,因此我们需要将它定义在 Function.prototype 对象上。
  2. call 方法的第一个参数必须是要调用的函数执行上下文对象,必须以 this 的形式传入。在使用 call 方法时,如果传入的上下文对象为 null 或者 undefined,则默认使用全局对象(浏览器中为 window 对象)作为执行上下文对象。
  3. 除了第一个参数外,call 方法可以接受任意多个参数,这些参数将会作为函数执行时的参数传递进去。在我们手动实现的 call 方法中,可以通过使用 arguments 对象来获取所有的参数,并通过 Function.prototype.apply() 方法来实现函数的调用。
  4. 在执行函数时,应该将函数本身作为上下文对象的一个属性,并在执行完毕后删除该属性,以避免对上下文对象造成污染。

Function.prototype.apply

apply方法与call方法非常相似,唯一的不同就是接收参数的形式不同。

apply方法接收数组形式的参数,call方法接收单独给出的一个或多个依次传入的参数

image.png