Javascript:当对象拥有函数时,为什么要在apply方法中传递相同的对象作为参数?

Javascript:当对象拥有函数时,为什么要在apply方法中传递相同的对象作为参数?,javascript,Javascript,我想用这个标题说的是: 在以下方面是否存在差异: argument = [arg1, arg2, arg3]; Foo.bar.apply(Foo, argument); 与之相比: Foo.bar(arg1, arg2, arg3); 除了显而易见的(论点与非论点) 对同一方法(bar)使用以下两种不同的“调用”方法的原因是什么?我知道apply与调用对象有关,但在这种情况下有区别吗 提供了很多关于申请的信息,但是我还没有找到一个好的答案来解释为什么要通过“我自己” 长话短说: /* Th

我想用这个标题说的是:

在以下方面是否存在差异:

argument = [arg1, arg2, arg3];
Foo.bar.apply(Foo, argument);
与之相比:

Foo.bar(arg1, arg2, arg3);
除了显而易见的(论点与非论点)

对同一方法(bar)使用以下两种不同的“调用”方法的原因是什么?我知道apply与调用对象有关,但在这种情况下有区别吗

提供了很多关于申请的信息,但是我还没有找到一个好的答案来解释为什么要通过“我自己”

长话短说:

/* This is the bar method in CFoo class */
CFoo.prototype.bar = function(a,b,c) {
  /* 
   * Magic things happen here,
   * and also...
   */
  if (a == "SomthingSpecial") {
    this.bar(a,b);
  }
}
bar被称为的大部分地方都是通过CFoo的全局实例来实现的

/* In the begining... */
Foo = new CFoo();

/* Some other place */
Foo.bar("Test", 3, function(v) {
    /* Some stuff */
});

/* And another place */
arr = ["Test2", 4, function(v) {
    /* Other stuff */
}];
Foo.bar.apply(Foo, arr);
编辑:对标题做了更多的解释。在@nils answer comment中回答。

使用了
.apply()
的“和另一个地方”代码显然希望使用现有数组作为函数调用的参数列表。在JavaScript中实现这一点的唯一(简单)方法是使用
.apply

换句话说,代码有一个数组:

arr = ["Test2", 4, function(v) {
    /* Other stuff */
}];
并希望得到的效果

Foo.bar("Test2", 4, function(v) { ... });
也就是说,它希望使用数组元素作为参数调用
Foo.bar()
。为此,它可以使用
.apply()
,但为了确保
是对对象
Foo
的引用,它将
Foo
作为第一个参数传递

因此,有两个要求结合在一起:

  • 函数
    Foo.bar()
    
  • 出于某种原因,已生成或计算了要传递到
    Foo.bar()
    的参数列表,该列表位于数组中
  • .apply()
    做两件事:

  • 第一个参数更改函数调用的上下文(
    this
  • 第二个参数是应用于函数的数组。因此,当调用
    bar
    时,数组中的每个值都将是一个参数值。这将导致
    a=arr[0]
    b=arr[1]
    c=arr[2]
  • 为了演示为什么需要传入
    Foo
    作为上下文,让我们看一个示例。如果要调用以下函数,它将失败,因为
    this
    将等于
    null

    Foo.bar.apply(null, arr); // null instead of Foo
    
    // in the function call...
    if (a == "SomthingSpecial") {
      this.bar(a,b); // this == null here
    }
    
    替代方法(EcmaScript 2015)

    如果您可以使用EcmaScript 2015并希望避免必须传递上下文,则可以使用:


    哦…我明白了。看完问题后。我想知道为什么?这是一个很好的技术是的。但代码比看起来更准确。问题是数组是在应用之前创建的,所以对我来说没有意义。如果数组是我立即购买的结果。@Mats无论数组在何处/如何创建,如果必须使用数组作为参数列表,则必须使用
    .apply()
    (或nils的答案中描述的新的
    ..
    运算符)。我得到了,但Foo.bar(a、b、c)是否有区别;和Foo.bar.apply(Foo,arr);其中arr=[a,b,c];?不直接。这实际上取决于你事先掌握的数据。如果您有一个数组(
    var arr=[a,b,c];
    ),请使用
    apply
    。如果您有单变量(
    var a='a';
    ),请直接调用
    bar
    。(正如波蒂在下面的评论中指出的那样)我选择你的答案作为我问题的最佳答案,因为问题归结为调用方法是否有差异。
    Foo.bar(...arr); // Spreading the array with the spread operator