当 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 关于如何创建一个对象,使用 apply
和 new .... ()
的组合,特别是使用以下替换 Something
和 Date
:
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)
进行调用。
作为 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 关于如何创建一个对象,使用 apply
和 new .... ()
的组合,特别是使用以下替换 Something
和 Date
:
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 toapply
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)
进行调用。