当你这样做时:
time2=time1;
...您不是在创建一个新 Date
对象,您只是从两个单独的变量中指向日期对象。只有一个对象,因此无论您查看哪个变量,您对其所做的任何更改都很自然。
让我们向它扔一些 ASCII 艺术:
time1 = new Date();
这给了我们:
+-------+
+ 时间1 +
+-------+ +--------------+
| 价值 |---------------->| 日期对象 |
+-------+ +--------------+
现在当你这样做时:
time2=time1;
我们有
+-------+
+ 时间1 |
+-------+
| 价值 |------+
+--------+ | +---------------+
+--------->| 日期对象 |
| +---------------+
+--------+ |
+ 时间2 | |
+--------+ |
| 价值 |------+
+-------+
和变量的值是对对象的引用,而不是它的副本。(所有对象都以这种方式工作。)您可以将对象引用视为在内存中找到对象的内存地址。(实际上是什么取决于实现。)time1
time2
Date
这与原语不同,其中变量的值实际上包含原语的数据,例如:
var n = 42;
结果是
+-----------+
+ n |
+-----------+
| 值:42 |
+-----------+
(理论上。事实上,字符串“原语”会表现得好像这是真的,但实际上可能存储得更像对象。没关系,字符串是不可变的,==
并且===
对于字符串原语比较它们的内容,所以我们不能真正分辨出区别,我们可以假装它们实际上包含在变量中。[只是为了真正令人困惑:JavaScript 也有Number
和String
objects,它们的行为类似于对象。])
请在下面回答您的问题:
在此期间,创建与先前存在的对象相同的第二个 javascript 对象的最有效方法是什么?
JavaScript 对象没有通用的“克隆”操作,因此答案因对象而异。有些对象不需要克隆,因为它们是不可变的(无法更改),因此不需要克隆(String
例如对象)。
要克隆date,很容易:
time2 = new Date(time1);
或者更高效:
time2 = new Date(+time1);
(因为+
告诉time1
对象将自己转换为数字,然后Date
构造函数使用该数字。没有它,time1
对象将被要求将自己转换为字符串,然后Date
构造函数将解析该字符串。仍然有效,但继续通过数字是一种微优化,几乎可以肯定是过早的优化——并且可能会干扰引擎可能想要使用的任何隐藏优化。所以我会选择time2 = new Date(time1);
。)