当你执行以下操作时:
date2=date1
你并没有创建一个新的Date
对象,而是只是指向来自两个不同变量的日期对象。只有一个对象,因此无论您查看哪个变量,对其进行的任何更改都会显而易见。
让我们用一些ASCII艺术来说明:
date1 = new Date();
这给我们带来了:
+-------+
+ date1 +
+-------+ +---------------+
| value |---------------->| 一个日期对象 |
+-------+ +---------------+
现在当你执行以下操作时:
date2=date1
我们有
+-------+
+ date1 |
+-------+
| value |------+
+-------+ | +---------------+
+--------->| 一个日期对象 |
| +---------------+
+-------+ |
+ date2 | |
+-------+ |
| value |------+
+-------+
date1和
date2变量的
value
是指向
Date
对象的引用,而不是它的副本。(所有对象都是这样工作的。) 你可以将一个
对象引用视为指向内存中对象位置的内存地址。 (它实际上取决于实现方式。)
这与
基本数据类型不同,其中变量的值实际上包含原始数据,例如:
var n = 42
结果为
+-----------+
+ n |
+-----------+
| value: 42 |
+-----------+
(理论上而言。实际上,字符串“原始值”会表现得好像是这样的,但实际上可能更像对象存储。不过没关系,字符串是不可变的,并且对于字符串“原始值”,==
和===
比较它们的内容,因此我们无法真正区分它们,并且可以假装它们实际上被变量包含。[仅仅为了让人困惑:JavaScript还有Number
和String
对象,它们的行为类似于对象。])
关于你下面的问题:
在此期间,创建一个与预先存在的对象完全相同的第二个javascript对象的最有效方法是什么?
JavaScript对象没有通用的“克隆”操作,因此答案因对象而异。有些对象不需要克隆,因为它们是不可变的(不能被改变),因此不需要克隆(例如String
对象)。
要克隆一个日期,很容易:
date2 = new Date(date1);
或者稍微更有效率一些的写法:
date2 = new Date(+date1);
(因为
+
会告诉
date1
对象将自己转换为数字,然后
Date
构造函数使用该数字。如果没有它,
date1
对象将被要求将自己转换为字符串,然后
Date
构造函数将解析该字符串。仍然有效,但通过数字进行微调几乎肯定是过早的优化,并且可能会干扰引擎想要使用的任何隐藏优化。所以我只会选择
date2 = new Date(date1);
。)
date2
被设置为指向date1
所指向的指针。 - James