JavaScript call() 方法 vs apply() 方法

2025 年 8 月 30 日 | 8 分钟阅读

JavaScript 等编程语言具有适应性,并提供了各种方法来处理 this 关键字和 函数 参数。call()apply() 方法是这类应用程序中最常用的两种技术。您可以使用这些方法中的任何一种来调用带有参数的函数并指定其值,但它们执行的方式略有不同。在此文章中,我们将通过理论和实践示例来了解这两种方法之间的差异,以便于学习和理解。

JavaScript call() Method vs apply() Method

call() 方法

call() 方法 使用给定的 this 值和单独提供的参数调用函数。当您确切知道需要传递多少参数时,它很有用。

语法

示例

立即执行

输出

Hello, Tom!

说明

  • 问候语和标点符号是 greet 函数接受的两个输入。
  • 我们创建的 person 对象的 name 属性设置为“Tom”。
  • 我们通过提供“Hello”和“!”作为参数,并使用 call() 方法将 this 上下文设置为 person 对象来调用 greet 函数。
  • 结果是 Hello, Tom!

apply() 方法

与 call() 类似,apply() 方法 也接受数组或类似数组的对象作为参数。当您希望向函数提供一个参数数组时,此过程会派上用场。

语法

示例

立即执行

输出

Hi, Abraham!!

说明

  • 与以前一样,greet 函数接受两个参数:问候语和标点符号。
  • 我们构建了一个 person 对象,并为其 name 属性值指定“Abraham”。
  • 我们通过提供 ['Hi', '!!'] 作为参数数组,并使用 apply() 方法将 this 上下文添加到 person 对象来调用 greet 函数。
  • 结果是 Hi, Abraham!!

call() 和 apply() 方法之间的区别

call() 和 apply() 方法是 JavaScript 中的函数方法,它们调用函数并将该函数的值设置为 this。它们都成功地将 this 的值传递给您指定的值并调用函数,它们在传递参数的方式上有所不同。让我们来看看这些差异。

1. 目的

  • call() 和 apply() 都用于请求具有特定 this 值或上下文的函数。
  • 它们使您能够控制查找 this 关键字用于请求函数的值,从而确保在运行时使用适当的潜在上下文调用函数。

2. 参数传递

  • call() 方法在 this 值之后将参数作为单独的值传递。
  • apply() 方法在 this 值之后将参数作为数组或类似数组的对象传递。

3. 性能

  • 对于少量固定数量的参数,call() 可能稍微更有效,因为它不需要 数组
  • apply() 在处理大型数组时可能会带来一些性能开销,因为它需要将参数放入数组中。

4. 灵活性

  • 在参数数量可变的情况下,call() 的灵活性较低,因为您需要单独传递每个参数。
  • apply() 在处理参数数组时更灵活。

5. 应用场景

  • 当您知道确切的参数数量并希望单独传递它们时,call() 是合适的。
  • 当您有一个参数数组或参数数量是动态的时,apply() 是合适的。

实际示例

我们应该检查更难以预测的示例,以更深入地了解 call() 和 apply() 的应用程序和优点。两种方法都有助于请求具有特定 this 上下文的函数,但它们在参数传递方式上有所不同。

1. 使用不同的 this 上下文调用函数

我们有两个对象 person1person2,它们具有不同的名称属性。我们将使用 call() 和 apply() 方法从 person1 调用一个方法并将其应用于 person2

使用 call()

示例

立即执行

输出

Hello Tom!

说明

call() 用于调用 person1 的 greet() 方法,但将 this 设置为 person2。参数(“Hello”和“!”)在 this 上下文之后单独传递。

使用 apply()

示例

立即执行

输出

Hello Tom!

说明

apply() 用于调用 person1 的 greet() 方法,但将 this 设置为 person2。参数作为数组(['Hello', '!'])传递,它们被解包并传递给方法。

2. 动态使用参数

我们将构建一个计算数字之和的函数。我们将使用 call() 和 apply() 以不同的方式传递数字。

使用 call()

示例

立即执行

输出

150

说明

call() 将数字作为参数单独传递给 sum 函数,并且 arguments 是函数内部的类数组对象,它允许我们循环并计算总和。

使用 apply()

示例

立即执行

输出

150

说明

apply() 用于调用 sum 函数,并将 this 设置为 null。数字数组作为单个参数传递给 apply(),并在函数内部作为单独的参数解包。

3. 全名格式化

我们可以构建一个包含名称的函数,并根据需要使用 call() 或 apply() 使用后缀和前缀来请求它。

使用 call()

示例

立即执行

输出

Mr. Tom Cruise Sr.

说明

call() 用于请求一个名为 getFullName 的函数来访问要返回的前缀和后缀值的模式,并在将其传递到控制台后选择要打印的名称。

使用 apply()

示例

立即执行

输出

Ms. Taylor Swift Jr.

说明

apply() 用于请求一个名为 getFullName 的函数来访问要返回的前缀和后缀值的模式,并在将其传递到控制台后选择要打印的名称。

call() 与 apply() 方法的比较表格表示

以下是比较 call() 和 apply() 方法的表格表示

特性call()apply()
用途使用指定的 this 值调用函数。使用指定的 this 值调用函数。
参数参数单独传递给程序。参数作为数组或类似数组的对象传递。
语法func.call (thisArg, arg1, arg2, …)func.apply (thisArg, [arg1, arg2, …])
灵活性对于可变参数,它的灵活性较低。对于动态参数,它更灵活。
示例greet.call (person, "Hello", "John")greet.apply (person, ["Hello", "John" ])
上下文 (this)this 被设置为第一个参数 (thisArg)this 被设置为第一个参数 (thisArg)
参数数组不,您必须一个接一个地传递参数。是的,参数必须作为组合数组传递。
性能使用较少参数通常更快。由于数组处理,对于大型数组效率较低。
常见用例当您知道确切的参数数量时。当参数是动态生成或已在数组中时。

结论

JavaScript 的 call()apply() 方法提供了以给定参数和上下文调用函数的强大方法。这两种方法应用参数的方式,call() 单独应用,apply() 作为数组应用,是它们之间的本质区别。监控这些区别并知道何时应用这两种方法可以帮助您构建更通用和可重用的代码。

总结

  • 如果您希望逐个单独传递参数,并且您知道要传递的参数数量,则使用 call() 方法。
  • 如果参数存储在数组中或它们的数量是动态的,则使用 apply() 方法。

call() 和 apply() 方法都通过对函数上下文 (this) 和参数的精确控制来帮助编写更灵活、可重用和可维护的 JavaScript。

常见问题解答 (FAQs)

1. call() 和 apply() 在 JavaScript 中的目的是什么?

call() 和 apply() 都用于使用特定的 this 上下文调用函数,这意味着更改函数内部 this 的值。当您希望在一个对象中定义的函数在另一个对象中使用时,这很有用。

2. 我应该何时使用 call() vs apply()?

  • 当您已经单独拥有参数时,可以使用 call()。
  • 当您的参数已在数组或类似数组的对象中时,例如 arguments 对象或 Nodelist,可以使用 apply()。

3. 我可以将它们与对象内部的方法一起使用吗?

是的。它们对于从一个对象借用方法并将其应用于另一个对象特别有用。

示例

立即执行

输出

John Doe

4. call() 或 apply() 有现代替代方案吗?

是的。您可以使用扩展运算符 (…) 与 call() 或直接在较新的代码中代替 apply()。

此外,对于 this 的永久绑定,您可以使用 bind() 方法。

5. call() 和 apply() 今天仍然相关吗?

是的,尽管 ES6 引入了扩展运算符,但 call() 和 apply() 仍然是 JavaScript 处理上下文 (this) 的基础,并且在许多情况下都很有用,尤其是在面向对象和函数式编程中。

6. call() 和 apply() 会返回任何东西吗?

是的。它们返回函数本身返回的任何内容,就像正常的函数调用一样。

7. call() 和 apply() 之间有什么区别?

唯一的区别是您如何将参数传递给函数

方法语法示例参数如何传递
call()func.call (thisArg, arg1, arg2, …)一个接一个地传递
apply()func.apply (this.Arg, [arg1, arg2, …])作为数组传递