使用Date对象调用Date构造函数

时间:2015-09-02 23:42:02

标签: javascript

Date的JS文档声称有四种方法可以使用Date构造函数。来自https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date

new Date();
new Date(value); // integer
new Date(dateString); // string
new Date(year, month[, day[, hour[, minutes[, seconds[, milliseconds]]]]]);

但是,通过传入有效的日期对象,似乎有第五种方法来使用构造函数。例如,以下在chrome控制台中工作正常:

date = new Date() // Wed Sep 02 2015 16:30:21 GMT-0700 (PDT)
date2 = new Date(date) // Wed Sep 02 2015 16:30:21 GMT-0700 (PDT)

它们是不同的对象,因此它似乎是一种复制日期的简单方法:

date2 === date // false
date.setMonth(1) // 1422923421090
date // Mon Feb 02 2015 16:30:21 GMT-0800 (PST)
date2 // Wed Sep 02 2015 16:30:21 GMT-0700 (PDT)

所以我的问题是:

  1. 为什么这不在官方文档中?我错过了什么吗?
  2. 这是官方支持的构造函数使用吗?它适用于所有平台/浏览器吗?
  3. 这是一种制作Date物品副本的安全方式,例如date2 = new Date().setTime(date.getTime())

2 个答案:

答案 0 :(得分:3)

直接来自ECMAScript 6 spec的相关部分:

  

如果Type(value)为Object且value具有[[DateValue]]内部插槽,   然后让tv成为thisTimeValue(值)。

基本上说如果你传递Date构造函数一个参数并且它是一个对象并且它有[[DateValue]]内部插槽,那么使用它来初始化新对象。

因此,您所看到的内容已记录在规范中。

以下是更多细节:

enter image description here

但是,ES5规范不一样,当你做你正在做的事情时会转换为字符串,然后由构造函数解析为字符串。虽然这可以将所有内容保留到秒,但它不会保留毫秒,因为默认字符串转换中不存在这些。因此,如果您想要一个完美的副本,那么您应该在ES5或更早版本中执行此操作:

var date = new Date();
var date2 = new Date(date.getTime());

答案 1 :(得分:0)

我现在建议反对。现在,根据Date对象的不同规范,浏览器会出现这种情况。

ES 6.0:



var d1 = new Date();
var d2 = new Date(d1.getTime());
//ES6.0 basically gets the property that holds the timestamp straight from the object.

document.getElementById('results').innerHTML = 'Assert: ' + d1.valueOf() + ' === ' + d2.valueOf() + ' ' + (d1.valueOf() === d2.valueOf());

<pre id="results"></pre>
&#13;
&#13;
&#13;

它确实比较完美但是......以下是ES5.1将如何处理:

&#13;
&#13;
var d1 = new Date();
var d2 = new Date(Date.parse(d1.toString()));
//ES5.1 will attempt to parse the string representation of the Date object.

document.getElementById('results').innerHTML = 'Assert: ' + d1.valueOf() + ' === ' + d2.valueOf() + ' ' + (d1.valueOf() === d2.valueOf());
&#13;
<pre id="results"></pre>
&#13;
&#13;
&#13;

它基本上得到了第一个Date对象的毫秒数(如果第一个日期对象没有毫秒,则断言可能会起作用,运行代码片段几次)。 Firefox目前似乎遵循ES5.1行为和Chrome ES6.0。无法真正说出他们何时开始采用它。

如果目的是克隆第一个Date对象,我绝对不会建议将Date对象作为新Date对象的构造函数传递。请改用Data.prototype.getTime()