如何在JavaScript中克隆Date对象

Árv*_*gép 460 javascript

将Date变量分配给另一个变量会将引用复制到SAME值.这意味着改变一个将改变另一个.我怎样才能实际克隆或复制该值?

Ste*_*son 682

使用Date对象的getTime()方法,该方法返回自1970年1月1日00:00:00(纪元时间)以来的毫秒数:

var date = new Date();
var copiedDate = new Date(date.getTime());
Run Code Online (Sandbox Code Playgroud)

在Safari 4中,您还可以编写:

var date = new Date();
var copiedDate = new Date(date);
Run Code Online (Sandbox Code Playgroud)

...但我不确定这是否适用于其他浏览器.(它似乎在IE8中工作).

  • 编写这个好解决方案的另一种方法是扩展Date原型:`Date.prototype.clone = function(){return new Date(this.getTime()); 然后你可以将其用作`copiedDate = date.clone();` (16认同)
  • `new Date(date)`与`new Date(date.getTime())`相同,因为JS在需要数字时会尝试调用`date.valueOf()`,而`date.valueOf()`是相同的作为`date.getTime()`,引用[Date.valueOf](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/valueOf?redirectlocale=en-US&redirectslug= JavaScript%2FReference%2FGlobal_Objects%2FDate%2FvalueOf)[Object.valueOf](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf?redirectlocale=en-US&redirectslug= JavaScript的%2FReference%2FGlobal_Objects%2FObject%2FvalueOf) (14认同)
  • 不要使用`new Date(date)`,使用`new Date(date.getTime()`或`new Date(date.valueOf)`代替,因为第一种方式可能导致至少Firefox和IE中日期之间的差异(未镀铬)例如使用`toISOString()`上Firefox中的两个日期产生` "2015-04-21T04:56:42.000Z".`和` "2015-04-21T04:56:42.337Z"`. (10认同)
  • 这个片段的JSON?听起来像这些人应该清楚他们的基础......就像把jQuery误认为JavaScript DOM一样. (9认同)
  • `copiedDate = new Date(date)`方法适用于IE6 +.在Firefox中,两个选项的速度相同. (6认同)
  • 新的Date(dateObject)是正确的。请参见[Date(value)构造函数]的说明(http://www.ecma-international.org/ecma-262/6.0/#sec-date-value),其中定义了日期对象的显式规则。在较早的规范中,如果不是字符串,则行为是在参数上调用`ToNumber`,因此这两种方法都应在正确实现该行为的任何浏览器中起作用。 (3认同)
  • 1970年之前的日期呢? (2认同)

Ant*_*nes 104

这是最干净的方法

let dat = new Date() 
let copyOf = new Date(dat.valueOf())

console.log(dat);
console.log(copyOf);
Run Code Online (Sandbox Code Playgroud)

  • @Steve:是的,但是getTime()可以"看起来"它只返回时间而不包括日期以及因此我对"最干净"的引用.坦率地说,Javascript中的Date类型是一个灾难区域,它首先应该是不可变的. (32认同)
  • "Date"对象的"valueOf()"方法产生与其"getTime()"方法(自纪元时间以来的毫秒数)相同的结果. (9认同)
  • 我同意.valueOf()更清楚.有时我会忘记并使用.getMilliseconds()b/c给我听起来像是指自纪元时间以来的平均毫秒数. (3认同)
  • +1 史蒂夫·哈里森:我想知道情况是否如此,感谢您的澄清。 (2认同)

Man*_*ngo 83

2021 年更新

\n

从一方面来说,克隆对象的概念Date听起来比实际情况更宏大。据我所知,\xe2\x80\x99s 只有一项实例数据,那就是存储的时间。我们\xe2\x80\x99真正做的是用相同的时间创建一个新对象。

\n

无论过去的情况如何,new Date()构造函数肯定接受一个Date对象作为单个参数:

\n
const date = new Date();        // With or without an argument.\nconst date2 = new Date(date);   // Clone original date.\n
Run Code Online (Sandbox Code Playgroud)\n

https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date中步骤 4(b) 的规范表明Date对象绝对是可接受的,并且这相当于new Date(date.valueOf()),如建议的上面的一些答案。正如我所说,你\xe2\x80\x99真正所做的就是Date用与另一个对象相同的时间创建一个新对象。

\n

您\xe2\x80\x99还会发现https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date上的文档已更新以包含此内容。

\n

  • 这应该是新接受的答案。 (8认同)

小智 24

var orig = new Date();
var copy = new Date(+orig);
Run Code Online (Sandbox Code Playgroud)

  • 除了你必须解释除了JS专家之外,除了JS +专家以外,还有什么神奇的`+`. (30认同)
  • :)`+`符号是unaray运算符.这意味着``new Date(Number(orig))``.更多信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Unary_plus (5认同)
  • 我最喜欢这种解决方案。 (3认同)
  • 非常精确和干净:) (3认同)

小智 15

简化版:

Date.prototype.clone = function () {
    return new Date(this.getTime());
}
Run Code Online (Sandbox Code Playgroud)

  • 你不要乱用内置物体 (64认同)
  • 你不应该捣乱你不拥有的物品.您应该制作一个新的副本,并将其称为SuperDate或其他东西,与您的范围.很多难以测试的错误都是由对象功能意外改变引起的. (3认同)

小智 7

我发现这个简单的指令也有效:

dateOriginal = new Date();
cloneDate = new Date(dateOriginal);
Run Code Online (Sandbox Code Playgroud)

但我不知道它是多么"安全".在IE7和Chrome 19中成功测试过.

  • 不要使用`new Date(date)`,使用`new Date(date.getTime()`或`new Date(date.valueOf)`代替,因为第一种方式可能导致至少Firefox和IE中日期之间的差异(未镀铬)例如使用`toISOString()`上Firefox中的两个日期产生` "2015-04-21T04:56:42.000Z".`和` "2015-04-21T04:56:42.337Z"`. (8认同)
  • 对于现在阅读本文的任何人来说,这**有效**,请忽略指出必须使用 `.getTime` 的旧评论。 (3认同)
  • 在旧版本的 Firefox 上可能是这样,但在最新版本上,“new Date(date)”工作正常。尝试一下: `let date = '2015-04-21T04:56:42.337Z'; 新的日期(日期).toISOString()`。结果与输入相同:`"2015-04-21T04:56:42.337Z"` (2认同)