12

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

var val = Math.max.apply(Math, data_array);

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

var val = Math.max(data_array);

谢谢。

4

5 回答 5

13

Math.max 默认不接受列表。“应用”允许您将列表解压缩为参数,以便 max 正常工作。

于 2011-05-09T12:06:21.180 回答
11

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

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

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

至于参数:

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

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");

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

于 2011-05-09T12:06:56.570 回答
2

为什么调用“应用”而不是直接调用函数?让我们有一个片段:

var obj = {a: "apply"};
func.call(obj, "parameter");
function func(para) {
    if(this.a === "apply"){
        console.log('apply'); 
     }
} 

在这里我们可以看到我们'this'在函数中使用(上下文),如果我们直接调用一个函数而不是我们没有任何上下文,那么它将使用window上下文,这是错误的。因此,如果您在函数中使用上下文而不是使用apply方法。

于 2013-12-13T12:37:51.440 回答
0

.apply当意图是调用带有参数值列表的可变参数函数时,通常使用它,例如

Math.max([value1[,value2, ...]])函数返回零个或多个数字中的最大值。

Math.max(10, 20); // 20
Math.max(-10, -20); // -10
Math.max(-10, 20); // 20

Math.max()方法不允许您传入数组。如果您有一个需要获取最大值的列表,您通常会使用Function.prototype.apply()调用此函数,例如

Math.max.apply(null, [10, 20]); // 20
Math.max.apply(null, [-10, -20]); // -10
Math.max.apply(null, [-10, 20]); // 20

但是,从 ECMAScript 6 开始,您可以使用扩展运算符

扩展运算符允许在需要多个参数(用于函数调用)或多个元素(用于数组字面量)的地方扩展表达式。

Math.max(...[10, 20]); // 20
Math.max(...[-10, -20]); // -10
Math.max(...[-10, 20]); // 20

使用可变参数运算符调用函数时,您甚至可以添加其他值,例如

Math.max(...[10, 20], 50); // 50
Math.max(...[-10, -20], 50); // 50
于 2014-12-18T01:35:27.877 回答
0

通常,您将使用apply()并且call()能够设置调用函数所属的上下文或对象。然后,该函数有效地成为该对象/上下文的方法,如果您需要访问上下文的字段,这将很有帮助。

这就是 Javascript 原生调用函数的方式:

  1. 从参数 1 到末尾创建一个参数列表 (argList)
  2. 第一个参数是thisValue
  3. 将此设置为 thisValue 和 argList 作为其参数列表调用函数

参考:了解 JavaScript 函数调用和Yehuda Katz的“this”

因此,当直接调用函数时,您实际上是在将默认上下文隐式传递给函数。当您未使用或指定时,Javascript通过'window'或作为上下文'undefined'call()apply()

答案还提供了一个示例,可能有助于理解用法

于 2015-10-26T21:25:05.263 回答