在查看 raphael 或 g.raphael 或其他库的源代码时,我注意到开发人员做了这样的事情:
var val = Math.max.apply(Math, data_array);
为什么不直接调用函数呢,比如:
var val = Math.max(data_array);
谢谢。
在查看 raphael 或 g.raphael 或其他库的源代码时,我注意到开发人员做了这样的事情:
var val = Math.max.apply(Math, data_array);
为什么不直接调用函数呢,比如:
var val = Math.max(data_array);
谢谢。
Math.max 默认不接受列表。“应用”允许您将列表解压缩为参数,以便 max 正常工作。
我认为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
为什么调用“应用”而不是直接调用函数?让我们有一个片段:
var obj = {a: "apply"};
func.call(obj, "parameter");
function func(para) {
if(this.a === "apply"){
console.log('apply');
}
}
在这里我们可以看到我们'this'
在函数中使用(上下文),如果我们直接调用一个函数而不是我们没有任何上下文,那么它将使用window
上下文,这是错误的。因此,如果您在函数中使用上下文而不是使用apply
方法。
.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
通常,您将使用apply()
并且call()
能够设置调用函数所属的上下文或对象。然后,该函数有效地成为该对象/上下文的方法,如果您需要访问上下文的字段,这将很有帮助。
这就是 Javascript 原生调用函数的方式:
参考:了解 JavaScript 函数调用和Yehuda Katz的“this”
因此,当直接调用函数时,您实际上是在将默认上下文隐式传递给函数。当您未使用或指定时,Javascript通过'window'
或作为上下文'undefined'
call()
apply()
该答案还提供了一个示例,可能有助于理解用法