.apply(Math,arrayName)如何工作? (JavaScript的)

时间:2014-07-02 21:49:16

标签: javascript this

有关如何在javascript中查找值数组的最小值或最大值的more than one stackoverflow问题。这不是那个问题。

我想知道为什么传递.apply()奇怪的东西,因为this参数仍然有用。尽管来自Aaron Crane的a good blog post关于Math对象的API如何变成现实,但仍有一些问题无法解决。

以下每个代码段均有效。我的问题是,怎么样?对this的任务究竟发生了什么,使其中的每一项都有效?

标准结构

var values = [45, 46, 47]
var min = Math.min.apply(Math, values);
alert(min); //45

一个奇怪的建筑,但范围可能很棘手......

var values = [45, 46, 47]
var min = Math.min.apply(this, values);
alert(min); //45

稍微怪异

var values = [45, 46, 47]
var min = Math.min.apply(global, values);
alert(min); //45

Weirder仍然,但也许好的b / c浏览器

var values = [45, 46, 47]
var min = Math.min.apply(window, values);
alert(min); //45

非常奇怪

var values = [45, 46, 47]
var min = Math.min.apply(null, values);
alert(min); //45

真的很奇怪

var values = [45, 46, 47]
var min = Math.min.apply(undefined, values);
alert(min); //45

4 个答案:

答案 0 :(得分:2)

使用.apply()时,第一个参数控制函数执行时this指针值的设置。在许多情况下,this值非常重要。在少数情况下,this值根本不在函数实现中使用(通常称为不对实例数据进行操作的静态函数)。如果未使用this,则设置this的内容并不重要,因此将.apply()的第一个参数设置为什么并不重要。< / p>

因此,在您的具体情况下,Math.min()Math.max()(可能还有所有Math.xxx()函数)根本不使用this指针,因为它们基本上都是不对实例数据进行操作的静态函数。因此,它设置的内容并不重要,因此您可以将任何您想要的内容作为Math.min.apply()的第一个参数传递,并且它不会更改函数调用的结果。


我认为仍然应该传递正确的值Math,因为当你做正常时this会是什么:

Math.min(x, y);

因此,要在使用Math.min()时将上述代码与.apply()呈现完全相同的情况,您可以这样做:

var arr = [x, y];
Math.min.apply(Math, arr);

IMO,这促进了正确的习惯和正确思考第一个论点应该是什么,因为它在其他情况下会很重要。

仅供参考,jQuery中的$.when.apply($, arr)也会出现类似的问题,它在实现中也没有使用this参数,因此可以将其称为$.when.apply(null, arr)甚至$.when.apply("foo", arr)。就个人而言,我更喜欢通过技术上正确的&#34;论证是第一个。

答案 1 :(得分:0)

TL; DR - Math.min()Math.max()实际上并没有使用传递给他们的this参数,只是让他们接受一个参数数组,因为本机API仅指定变量列表。 .apply() 可以接受参数数组,这就是使用它的原因。

我的猜测是Math作为this参数传递,只是为了清洁&#39;缘故。

感谢@Jonathan Lonowski和@Niet the Dark Absol。

答案 2 :(得分:0)

apply对其第一个参数的作用是简单地为调用它的函数设置上下文(this)。

让我们说,你有一个像这样的对象:

var obj = {
    a: 1,
    b: function () {
        return this.a;
    },
    c: function () {
        return 3;
    }
}

如果您致电obj.b(),您将获得1作为返回值,因为此方案中的this是通过前面b调用obj来定义的它(this === obj)。要更改它,您可以使用apply

obj.b.apply({a:2});

这将返回2,因为您现在明确将this设置为{a:2}

但是:如果你有一个内部没有使用this的函数,那么this的值是什么并不重要。所以你可以打电话:

obj.c();

或其中之一:

obj.apply.c(null);
obj.apply.c(undefined);
obj.apply.c("xyz");

但是你总会得到相同的结果3。这就像设置一个你从未使用过的变量。无论它有什么价值,它都不会影响结果。

显然Math.min不使用this因此在传递“无效”上下文时不会中断。

答案 3 :(得分:0)

这(可以这么说)是JavaScript中一个棘手的部分。

当你有一个功能时,会有一个名为this的神奇变量。根据您调用函数的方式,其上下文设置不同。

function myFunction() {
  return this;
}

var myObject = {
  fn: function() {
    return this;
  }
};

myFunction();  // the global object. `window` in browsers, `global` in Node.js
myFunction.apply(Math);  // Math
myFunction.apply({ hello: "world" });  // { hello: "world" }

myObject.fn();               // myObject
myObject.fn.apply(myObject); // myObject
myObject.fn.apply(Math);     // Math

上述示例的原因是min根本不使用this,因此您可以将其分配给您想要的任何内容。