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

发布于 2024-11-06 02:42:03 字数 221 浏览 5 评论 0原文

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

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

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

var val = Math.max(data_array);

谢谢。

When looking at the source code for raphael or g.raphael or other libraries I've noticed the developer does something like this:

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

Why not just invoke the function directly, such as:

var val = Math.max(data_array);

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

话少心凉 2024-11-13 02:42:03

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

Math.max won't accept a list by default. "apply" allows you to unpack the list to arguments so that max works correctly.

横笛休吹塞上声 2024-11-13 02:42:03

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

您可以分配不同的this对象
当调用现有函数时。
this 指的是当前对象,即
调用对象。通过申请,您可以
写一次方法然后继承
它在另一个对象中,而没有
重写新的方法
对象。

apply 与 call 非常相似,除了
对于它支持的参数类型。
您可以使用参数数组代替
一组命名的参数。和
apply,你可以使用数组文字,
例如, fun.apply(this, [name,
value]),或一个 Array 对象,对于
例如, fun.apply(this, new
数组(名称,值))。

至于参数:

thisArg
确定 fun 中 this 的值。如果 thisArg 为 null 或
未定义,this 将是全局的
目的。否则,这将是相等的
到 Object(thisArg) (这是 thisArg
如果 thisArg 已经是一个对象,或者
字符串、布尔值或数字(如果 thisArg)
是一个原始值
对应类型)。因此,它是
this == 的类型始终为真
函数执行时为“对象”。

argsArray
对象的参数数组,指定使用的参数
fun 应该被调用,或者 null 或
如果不应该有任何参数,则为未定义
提供给函数。

该文档给出了 apply 用例的一个很好的例子。在下面的示例中,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 构造函数的参数数组。

I think the explanation from the Mozilla Docs describes it well:

You can assign a different this object
when calling an existing function.
this refers to the current object, the
calling object. With apply, you can
write a method once and then inherit
it in another object, without having
to rewrite the method for the new
object.

apply is very similar to call, except
for the type of arguments it supports.
You can use an arguments array instead
of a named set of parameters. With
apply, you can use an array literal,
for example, fun.apply(this, [name,
value]), or an Array object, for
example, fun.apply(this, new
Array(name, value)).

As for the parameters:

thisArg
Determines the value of this inside fun. If thisArg is null or
undefined, this will be the global
object. Otherwise, this will be equal
to Object(thisArg) (which is thisArg
if thisArg is already an object, or a
String, Boolean, or Number if thisArg
is a primitive value of the
corresponding type). Therefore, it is
always true that typeof this ==
"object" when the function executes.

argsArray
An argument array for the object, specifying the arguments with which
fun should be called, or null or
undefined if no arguments should be
provided to the function.

The docs give a good example of a use case for apply. In the example below, apply is used to chain a constructor:

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

Notice that in the prod_dept constructor, the this supplied refers to the prod_dept object, and arguments is an array of arguments passed to the product constructor.

謸气贵蔟 2024-11-13 02:42:03

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

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

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

Why invoke “apply” instead of calling function directly? Let's have a snippet:

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

Here we can see we are using 'this' (context) within a function, If we directly call a func than we don't have any context, than it will take window context, which is wrong. So, if you are using context within your function than use apply method.

阳光的暖冬 2024-11-13 02:42:03

当目的是使用参数值列表调用可变参数函数时,通常会使用 .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 is often used when the intention is to invoke a variadic function with a list of argument values, e.g.

The Math.max([value1[,value2, ...]]) function returns the largest of zero or more numbers.

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

The Math.max() method doesn't allow you to pass in an array. If you have a list of values of which you need to get the largest, you would normally call this function using Function.prototype.apply(), e.g.

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

However, as of the ECMAScript 6 you can use the spread operator:

The spread operator allows an expression to be expanded in places where multiple arguments (for function calls) or multiple elements (for array literals) are expected.

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

When calling a function using the variadic operator, you can even add additional values, e.g.

Math.max(...[10, 20], 50); // 50
Math.max(...[-10, -20], 50); // 50
北凤男飞 2024-11-13 02:42:03

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

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

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

函数 参考: 理解 JavaScript 函数调用和“this” 作者:Yehuda Katz

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

这个答案还给出了一个可能有助于理解用法的示例

Generally you would use apply() and call() to be able to set the context or the object to which the calling function belongs to. The function then effectively becomes a method of that object/context which is helpful if you'll need to access the fields of the context.

This is how Javascript natively invokes functions:

  1. Make an argument list (argList) out of parameters 1 through the end
  2. The first parameter is thisValue
  3. Invoke the function with this set to thisValue and the argList as its argument list

Reference: Understanding JavaScript Function Invocation and "this" by Yehuda Katz

So, when calling a function directly you are actually implicitly passing in a default context to the function. Javascript passes 'window' or 'undefined' as context when you don't specify it using call() or apply()

This answer also gives an example which might help in understanding the usage

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文