当 thisArg 与后续 args 属于同一数组时,function.prototype.apply 如何工作

How does function.prototype.apply work when thisArg is part of the same array as subsequent args

作为 date/temperature 散点图的数据,我希望能够使用类似日期的字符串来键入数据,以下是我设计的结构:

  var dateTemperatures = {
      '[2016,8,29]': {low: 63, high: 94},
      '[2016,9,2]': {low: 59, high: 81},
      '[2016,9,1]': {low: 58, high: 85}
  }

想法是我可以在键上调用 JSON.parse,并具有创建日期所需的参数。然后我发现 this Whosebug answer 关于如何创建一个对象,使用 applynew .... () 的组合,特别是使用以下替换 SomethingDate:

var s = new (Function.prototype.bind.apply(Something, [null, a, b, c]));

它就像一个魅力,例如在我为订购 "Date" 键而设计的以下函数中:

  function orderTemperatureDates(dateTemperatures) {
      var orderedDates = [];

      for (var temperatureDate in dateTemperatures) {
          var YMD = JSON.parse(temperatureDate);
          YMD.unshift(null); //standard first argument to .apply()
          orderedDates.push(new (Function.prototype.bind.apply(Date, YMD)));
      }

      return orderedDates.sort(function(a,b){return a.getTime() - b.getTime()});
  }

CONSOLE/LOG/OUTPUT:

[Thu Sep 29 2016 00:00:00 GMT-0500 (Central Daylight Time), Sat Oct 01 2016 00:00:00 GMT-0500 (Central Daylight Time), Sun Oct 02 2016 00:00:00 GMT-0500 (Central Daylight Time)]

回到引用的 Whosebug 答案中的示例行,这是如何工作的?因为根据 documentation here,我的理解是 null 可以是 apply 的第一个参数,然后是其余参数,但在示例和我的代码中,null 和所有剩余参数参数是同一个数组的一部分。

My understanding is that null can be the first argument to apply followed by the remaining argument

是的,您 可以null 作为 apply 的第一个参数传递 您想要 this 方法内部的值是 null (或者通常不关心它)。但这里不是这样。

new (Function.prototype.bind.apply(Date, [null, 2016, 8, 29])) 中,我们不将 null 作为第一个参数传递给 apply,因为我们不希望那样。我们正在应用 bind 方法,我们需要将它与其余参数一起应用到 Date。调用等同于

new (Date.bind(null, 2016, 8, 29))

我们将 null 作为第一个参数传递给 bind,因为我们不关心在使用 [=25 调用绑定函数时无论如何都会被忽略的值=]关键字。

看看这个例子:

function constructor(a, b, c) {
  "use strict";
  console.log(this, a, b, c);
}
var bound = constructor.bind(null, 1, 2, 3);
bound();
new bound();


如果知道YMD总是三个元素,那么写new Date(YMD[0], YMD[1], YMD[2])就容易多了。如果您使用的是 ES6,您还可以使用扩展语法 new Date(...YMD) 进行调用。