0

我正在尝试通过各种 j/script 本机日期对象方法更新日期对象,但对为什么更改似乎应用于页面上的所有日期对象感到困惑。

我最初发现了一篇建议向日期原型添加方法的帖子,但这改变了所有日期对象。然后我简化并发现两个日期仍在更新。我将不胜感激有关如何防止这种情况的任何建议。我想要的是通过看起来有点像这样的东西的starTime和endTime。(注意:我最终会变成一个函数)。

time1 = new Date();
alert(time1);//returns Sat May 26 11:15:41 EDT 2012
time2=time1;
time2.setMinutes(time2.getMinutes()+10);
alert(time1); //returns Sat May 26 11:25:41 EDT 2012
alert(time2);//returns Sat May 26 11:25:41 EDT 20112  

问题:如果我只更新 date2,为什么 date2=date1。

4

3 回答 3

5

当你这样做时:

time2=time1;

...您不是在创建一个 Date对象,您只是从两个单独的变量中指向日期对象。只有一个对象,因此无论您查看哪个变量,您对其所做的任何更改都很自然。

让我们向它扔一些 ASCII 艺术:

time1 = new Date();

这给了我们:

+-------+
+ 时间1 +
+-------+ +--------------+
| 价值 |---------------->| 日期对象 |
+-------+ +--------------+

现在当你这样做时:

time2=time1;

我们有

+-------+
+ 时间1 |
+-------+
| 价值 |------+
+--------+ | +---------------+
               +--------->| 日期对象 |
               | +---------------+
+--------+ |
+ 时间2 | |
+--------+ |
| 价值 |------+
+-------+

和变量的是对对象的引用,而不是它的副本。(所有对象都以这种方式工作。)您可以将对象引用视为在内存中找到对象的内存地址。(实际上是什么取决于实现。)time1time2Date

这与原语不同,其中变量的值实际上包含原语的数据,例如:

var n = 42;

结果是

+-----------+
+ n |
+-----------+
| 值:42 |
+-----------+

理论上。事实上,字符串“原语”会表现得好像这是真的,但实际上可能存储得更像对象。没关系,字符串是不可变的,==并且===对于字符串原语比较它们的内容,所以我们不能真正分辨出区别,我们可以假装它们实际上包含在变量中。[只是为了真正令人困惑:JavaScript 也有NumberString objects,它们的行为类似于对象。])


请在下面回答您的问题:

在此期间,创建与先前存在的对象相同的第二个 javascript 对象的最有效方法是什么?

JavaScript 对象没有通用的“克隆”操作,因此答案因对象而异。有些对象不需要克隆,因为它们是不可变的(无法更改),因此不需要克隆(String例如对象)。

要克隆date,很容易:

time2 = new Date(time1);

或者高效:

time2 = new Date(+time1);

(因为+告诉time1对象将自己转换为数字,然后Date构造函数使用该数字。没有它,time1对象将被要求将自己转换为字符串,然后Date构造函数将解析该字符串。仍然有效,但继续通过数字是一种微优化,几乎可以肯定是过早的优化——并且可能会干扰引擎可能想要使用的任何隐藏优化。所以我会选择time2 = new Date(time1);。)

于 2012-05-26T15:21:57.877 回答
1

到目前为止发布的两个 答案都是正确的。解决方案是创建第二个使用相同内部毫秒值的日期,从第一个复制:

var time1 = new Date();
var time2 = new Date(time1.getTime());

现在您有两个不同的日期实例,您可以彼此独立地操作它们。

var time1 = new Date();
alert(time1); // Sat May 26 2012 11:26:16 GMT-0400 (EDT)
var time2 = new Date(time1.getTime());
time2.setMinutes(time2.getMinutes()+10);
alert(time1); // Sat May 26 2012 11:26:16 GMT-0400 (EDT)
alert(time2); // Sat May 26 2012 11:36:16 GMT-0400 (EDT)

更多阅读:日期 - MDN

于 2012-05-26T15:25:15.767 回答
0

当你这样做时:

time1 = new Date();  // <-- creates a new Date object
time2 = time1;       // <-- time2 gets passed a reference to the time1 object
                     //     making them effectively the same

您在第一行创建了一个 Date 对象,但第二行并没有创建另一个 Date 对象,它只是指向或引用已经创建的 Date 对象。这是许多面向对象编程语言的共同特征。

于 2012-05-26T15:22:58.630 回答