异同
相同点
都能够改变方法的执行上下文 (执行环境), 将一个对象的方法交给另一个对象来执行, 并且是立即执行
不同点
call 方法从第二个参数开始可以接收任意个参数, 每个参数会映射到相应位置的 func 的参数上, 可以通过参数名调用, 但是如果将所有的参数作为数组传入, 它们会作为一个整体映射到 func 对应的第一个参数上, 之后参数都为空
- function func(a, b, c) {}
- func.call(obj, 1, 2, 3)
- // function 接收到的参数实际上是 1,2,3
- func.call(obj, [1, 2, 3])
- // function 接收到的参数实际上是 [1,2,3],undefined,undefined
apply 方法最多只有两个参数, 第二个参数接收数组或者类数组, 但是都会被转换成类数组传入 func 中, 并且会被映射到 func 对应的参数上.
- func.apply(obj, [1,2,3])
- // function 接收到的参数实际上是 1,2,3
- func.apply(obj, {
- 0: 1,
- 1: 2,
- 2: 3,
- length: 3
- })
- // function 接收到的参数实际上是 1,2,3
两个方法该如何选择?
跟简单, 根据你要传入的参数来做选择, 不需要传参或者只有 1 个参数的时候, 用 call, 当要传入多个对象时, 用 apply
或者, 如果需要传入的参数已经是一个数组或者类数组了, 就用 apply, 如果还是单独的需要逐个传入的, 可以考虑使用 call
[其他用途 -- 对象继承]
由于可以改变 this 的指向, 所以也就可以实现对象的继承.
- function superClass () {
- this.a = 1;
- this.print = function () {
- console.log(this.a);
- }
- }
- function subClass () {
- superClass.call(this);
- this.print();
- }
- subClass();
- // 1
subClass 通过 call 方法, 继承了 superClass 的 print 方法和 a 变量, 同时 subClass 还可以扩展自己的其他方法.
来源: https://www.cnblogs.com/PearlRan/p/9684024.html