为什么要调用"apply"而不是直接调用函数?

cod*_*aig 12 javascript splat

在查看raphael或g.raphael或其他库的源代码时,我注意到开发人员做了类似这样的事情:

var val = Math.max.apply(Math, data_array);
Run Code Online (Sandbox Code Playgroud)

为什么不直接调用函数,例如:

var val = Math.max(data_array);
Run Code Online (Sandbox Code Playgroud)

谢谢.

Juh*_*nen 13

默认情况下,Math.max不接受列表."apply"允许您将列表解压缩到参数,以便max可以正常工作.


McS*_*tch 11

我认为Mozilla Docs的解释很好地描述了它:

调用现有函数时,可以指定不同的对象. 指的是当前对象,即调用对象.使用apply,您可以编写一次方法,然后在另一个对象中继承它,而不必重写新对象的方法.

apply与call非常相似,除了它支持的参数类型.您可以使用参数数组而不是命名的参数集.使用apply,您可以使用数组文字,例如fun.apply(this,[name,value])或Array对象,例如fun.apply(this,new Array(name,value)).

至于参数:

thisArg 确定这个内部乐趣的价值.如果thisArg为null或未定义,则将是全局对象.否则,这将等于Object(thisArg)(如果thisArg已经是对象,则为thisArg,如果thisArg是相应类型的原始值,则为String,Boolean或Number).因此,当函数执行时,这个=="对象"的类型总是正确的.

argsArray 对象的参数数组,指定应调用fun的参数,如果不应向函数提供参数,则为null或undefined.

文档提供了一个用于应用的用例的好例子.在下面的示例中,apply用于链接构造函数:

function product(name, value)
{
  this.name = name;
  if (value >= 1000)
    this.value = 999;
  else
    this.value = value;
}

function prod_dept(name, value, dept)
{
  this.dept = dept;
  product.apply(this, arguments);
}
prod_dept.prototype = new product();

// since 5 is less than 1000 value is set
var cheese = new prod_dept("feta", 5, "food");

// since 5000 is above 1000, value will be 999
var car = new prod_dept("honda", 5000, "auto");
Run Code Online (Sandbox Code Playgroud)

请注意,在prod_dept构造函数中,this提供的引用是prod_dept对象,并且arguments是传递给product构造函数的参数数组.