15

这适用于 Chrome:

var dateArray = [2012, 6, 5];
var dateObject = new Date(dateArray);

我得到了 2012 年 6 月 5 日。我还尝试了 Android 浏览器,得到了相同的结果。但是,这在 Firefox 或 Safari 中不起作用。我可以说:

var dateObject = new Date(2012, 6, 5);

但这应该是 2012 年 7 月 5 日,这也是我从 Chrome 中得到的。

我的问题:ECMA 标准的第一个示例部分是什么?只是 Chrome 更先进,我可以期待其他浏览器在未来支持它吗?或者它只是为了便携性而应该避免的一些 v8 主义?

我一直在尝试查找这种特定形式的 Date 构造函数的引用,但找不到任何引用。

4

4 回答 4

24

ES5 规范详细说明了构造函数的new Date(value)形式。Date在处理这种形式的算法中,value通过调用对象的[[DefaultValue]]内部方法将其转换为原始值。

将数组转换为原始值基本上是通过将数组转换为字符串来完成的。将数组转换为字符串 ( Array.prototype.toString) 实际上与调用dateArray.join().

因此,您对Date构造函数的调用实际上将如下所示:

var dateObject = new Date("2012,6,5");

如果该字符串可以被Date.parse方法识别,您将得到一个Date实例。

这种形式的Date构造函数也在MDN 上列为new Date(dateString).

当您传递一个数组时,Firefox 似乎会失败,但如果您传递该数组的字符串表示形式,它就会成功。我会说这可能是一个 Firefox 错误,但我可能误解了 ES5 规范。

于 2012-07-02T09:56:40.527 回答
15

您可以在 ES6中使用传播语法。

let dateArray = [2012, 6, 5];
let dateObject = new Date(...dateArray);

console.log('Spread:', dateObject);
console.log('Direct:', new Date(2012, 6, 5));

于 2016-11-23T06:53:29.123 回答
4

这个怎么样:

new (Function.prototype.bind.apply(
   Date, [null].concat([2011, 11, 24])
))

您可以使用数组项作为参数apply调用您创建的新函数。bind

来源:http ://www.2ality.com/2011/08/spreading.html

于 2014-10-27T14:02:18.323 回答
2

根据Jure 的回答。我已经在评论中澄清了Sergio 的问题,表明这null实际上是电话的范围。

function newInstance(clazz, arguments, scope) {
  return new (Function.prototype.bind.apply(clazz, [scope].concat(arguments)));
}

// Scope is not needed here.
var date = newInstance(Date, [2003, 0, 2, 4, 5, 6]);

// 1/2/2003, 4:05:06 AM (Locale = US EST)
document.body.innerHTML = date.toLocaleString();

于 2016-04-04T16:57:34.340 回答