js apply使用,从入门到精通

在 JavaScript 中,apply 是函数对象的一个方法,用于调用函数并显式指定 this 的值,同时以数组形式传递参数。它与 call 方法类似,区别在于 apply 接受参数数组,而 call 接受参数列表。让我们从入门到精通,逐步通过示例讲解 apply 的用法。


基础概念

  • 语法
  • thisArg:函数执行时 this 的绑定对象。
  • argsArray:一个数组或类数组对象,函数的参数会从中依次取出。
  • 返回值:函数的执行结果。
  • 作用:改变函数的 this 指向,并传入参数执行函数。

从入门到精通的示例

1. 入门:基本用法

  • 场景:简单调用函数,指定 this
  • 示例
  • 解释
  • this 被绑定到 person 对象。
  • 参数 ["Hello", "!"] 被解构为 greeting = "Hello"punctuation = "!"

2. 初级:与数组参数结合

  • 场景:已有参数数组,直接传递给函数。
  • 示例
  • 解释
  • this 不重要时,可以传 nullundefined
  • numbers 数组被展开为 sum(1, 2, 3)

3. 中级:借用方法

  • 场景:用一个对象的函数操作另一个对象。
  • 示例
  • 解释
  • 类数组对象 arrayLike 没有 slice 方法。
  • 通过 apply 借用 Array.prototype.slice,将 this 绑定到 arrayLike,将其转为真正的数组。
  • 补充:这在 ES6 前常用于类数组(如 arguments)转数组,现在可以用 Array.from 或扩展运算符 ...

4. 中高级:结合 arguments 对象

  • 场景:在函数内部动态处理不定参数。
  • 示例
  • 解释
  • arguments 是一个类数组,包含所有传入参数。
  • apply 借用 join 方法,将 arguments 转为字符串,中间用 ", " 分隔。

5. 高级:实现函数柯里化

  • 场景:利用 apply 实现参数的逐步传递。
  • 示例
  • 解释
  • curry 函数将 multiply 转为柯里化形式。
  • apply 用于动态地将累计的参数应用到目标函数上。

6. 精通:结合 Proxy 拦截函数调用

  • 场景:在 Proxy 中用 apply 增强函数行为。
  • 示例
  • 解释
  • Proxyapply 陷阱拦截函数调用。
  • 在陷阱中用 target.apply 执行原始函数,并对结果加工(转为大写)。

7. 精通:性能优化与函数组合

  • 场景:用 apply 实现函数管道(pipeline)。
  • 示例
  • 解释
  • pipe 将多个函数组合成一个,从左到右依次执行。
  • apply 用于动态调用每个函数,并传递上一步的结果。

注意事项

  1. call 的区别
  • call(thisArg, arg1, arg2, ...):参数逐个传递。
  • apply(thisArg, [arg1, arg2, ...]):参数以数组形式传递。
  • 示例:
    javascript function test(a, b) { console.log(this, a, b); } test.call({ id: 1 }, 2, 3); // { id: 1 }, 2, 3 test.apply({ id: 1 }, [2, 3]); // { id: 1 }, 2, 3
  1. 替代方案
  • ES6 后,扩展运算符 ... 可以部分替代 apply
    javascript const numbers = [1, 2, 3]; console.log(Math.max(...numbers)); // 3 // 等价于 Math.max.apply(null, numbers)
  1. 性能
  • 在现代 JavaScript 中,apply 的性能稍逊于 call...,但差异微乎其微,除非在极端循环中。

总结

  • 入门:理解 apply 的基本用法,改变 this 和传递数组参数。
  • 进阶:利用 apply 借用方法、处理动态参数。
  • 精通:结合现代特性(如 Proxy)或实现复杂逻辑(如柯里化、管道)。