Movatterモバイル変換


[0]ホーム

URL:


  1. 面向开发者的 Web 技术
  2. JavaScript
  3. JavaScript 参考
  4. JavaScript 标准内置对象
  5. Function
  6. Function.prototype.apply()

此页面由社区从英文翻译而来。了解更多并加入 MDN Web Docs 社区。

View in EnglishAlways switch to English

Function.prototype.apply()

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since ⁨2015年7月⁩.

Function 实例的apply() 方法会以给定的this 值和作为数组(或类数组对象)提供的arguments 调用该函数。

尝试一下

const numbers = [5, 6, 2, 3, 7];const max = Math.max.apply(null, numbers);console.log(max);// Expected output: 7const min = Math.min.apply(null, numbers);console.log(min);// Expected output: 2

语法

js
apply(thisArg)apply(thisArg, argsArray)

参数

thisArg

调用func 时提供的this 值。如果函数不处于严格模式,则nullundefined 会被替换为全局对象,原始值会被转换为对象。

argsArray可选

一个类数组对象,用于指定调用func 时的参数,或者如果不需要向函数提供参数,则为nullundefined

返回值

使用指定的this 值和参数调用函数的结果。

描述

备注:这个函数与call() 几乎完全相同,只是函数参数在call() 中逐个作为列表传递,而在apply() 中它们会组合在一个对象中,通常是一个数组——例如,func.call(this, "eat", "bananas")func.apply(this, ["eat", "bananas"])

通常情况下,在调用函数时,函数内部的this 的值是访问该函数的对象。使用apply(),你可以在调用现有函数时将任意值分配给this,而无需先将函数作为属性附加到对象上。这使得你可以将一个对象的方法用作通用的实用函数。

你还可以使用任何类数组对象作为第二个参数。实际上,这意味着它需要具有length 属性,并且整数(“索引”)属性的范围在(0..length - 1) 之间。例如,你可以使用一个NodeList,或者像{ 'length': 2, '0': 'eat', '1': 'bananas' } 这样的自定义对象。你还可以使用arguments,例如:

js
function wrapper() {  return anotherFn.apply(null, arguments);}

使用剩余参数和参数的展开语法,可以重写为:

js
function wrapper(...args) {  return anotherFn(...args);}

一般而言,fn.apply(null, args) 等同于使用参数展开语法的fn(...args),只是在前者的情况下,args 期望是类数组对象,而在后者的情况下,args 期望是可迭代对象

警告:不要使用apply() 进行构造函数链式调用(例如,实现继承)。这会将构造函数作为普通函数调用,这意味着new.targetundefined,从而类会抛出错误,因为它们不能在没有new 的情况下调用。请改用Reflect.construct()extends

示例

用 apply() 将数组各项添加到另一个数组

你可以使用Array.prototype.push() 方法将元素追加到数组中。因为push() 接受可变数量的参数,所以你也可以一次性添加多个元素。但是,如果你将一个数组传递给push(),它实际上会将该数组作为单个元素添加,而不是逐个添加元素,导致最终得到一个数组内嵌的数组。另一方面,Array.prototype.concat() 在这种情况下具有期望的行为,但它不会将元素追加到已有数组中,而是创建并返回一个新数组。

在这种情况下,你可以使用apply 隐式地将一个数组作为一系列参数展开。

js
const array = ["a", "b"];const elements = [0, 1, 2];array.push.apply(array, elements);console.info(array); // ["a", "b", 0, 1, 2]

使用展开语法可以达到相同的效果。

js
const array = ["a", "b"];const elements = [0, 1, 2];array.push(...elements);console.info(array); // ["a", "b", 0, 1, 2]

使用 apply() 和内置函数

巧妙地使用apply() 可以让你在某些情况下使用内置函数来完成一些任务,而这些任务通常需要手动遍历集合(或使用展开语法)。

例如,我们可以使用Math.max()Math.min() 来找出数组中的最大值和最小值。

js
// 数组中的最小/最大值const numbers = [5, 6, 2, 3, 7];// 用 apply 调用 Math.min/Math.maxlet max = Math.max.apply(null, numbers);// 这等价于 Math.max(numbers[0], …) 或 Math.max(5, 6, …)let min = Math.min.apply(null, numbers);// 与基于简单循环的算法相比max = -Infinity;min = +Infinity;for (let i = 0; i < numbers.length; i++) {  if (numbers[i] > max) {    max = numbers[i];  }  if (numbers[i] < min) {    min = numbers[i];  }}

但要注意:通过使用apply()(或展开语法)来处理任意长的参数列表,你可能会超过 JavaScript 引擎的参数长度限制。

调用具有太多参数的函数(即超过数万个参数)的后果是未指定的,并且在不同的引擎中会有所不同。(JavaScriptCore 引擎将参数限制硬编码为 65536。)大多数引擎会抛出异常;但并没有规范要求阻止其他行为,例如任意限制应用函数实际接收的参数数量。为了说明后一种情况:假设这样的引擎限制为四个参数(实际限制当然要高得多),那么在上面的示例中,传递给apply 的参数将变为5, 6, 2, 3,而不是完整的数组。

如果你的值数组可能会增长到数万个,可以使用混合策略:将数组的片段分批通过apply 调用函数:

js
function minOfArray(arr) {  let min = Infinity;  const QUANTUM = 32768;  for (let i = 0; i < arr.length; i += QUANTUM) {    const submin = Math.min.apply(      null,      arr.slice(i, Math.min(i + QUANTUM, arr.length)),    );    min = Math.min(submin, min);  }  return min;}const min = minOfArray([5, 6, 2, 3, 7]);

规范

Specification
ECMAScript® 2026 Language Specification
# sec-function.prototype.apply

浏览器兼容性

参见

Help improve MDN

Learn how to contribute

This page was last modified on byMDN contributors.


[8]ページ先頭

©2009-2025 Movatter.jp