Javascript日期变量赋值

Javascript date variable assignment

本文关键字:赋值 变量 日期 Javascript      更新时间:2023-09-26
var date1 = new Date();  
date1.setFullYear(2011, 6, 1);  
// 2011-07-01, ok  
console.log(date1);
// set date2 the same date as date1  
var date2 = date1;
// ...
// now I'm gonna set a new date for date2  
date2.setFullYear(2011, 9, 8);
// 2011-10-08, ok  
console.log(date2);
// 2011-10-08, wrong, expecting 2011-07-01  
// I didn't assign a new date to date1  
// WHY is date1 changed?  
console.log(date1);

日期是对象,所以它被指定为引用-简单的方法是

date2 = new Date( date1 );

当你这样做的时候:

date2=date1;

…您没有创建一个新的 Date对象,您只是从两个独立的变量指向日期对象。只有一个对象,所以你对它所做的任何改变都是明显的,不管你查看的是哪个变量。

让我们在上面添加一些ascii图像:

date1 = new Date();

我们得到:

<前>+-------++ date1 ++-------+ +---------------+| value |---------------->| a Date对象|+-------+ +---------------+

现在当你这样做的时候:

date2=date1;
我们

<前>+-------++ date1 |+-------+| value |------++-------+ | +---------------++--------->| a Date对象|| +---------------++-------+ |+ date2 | |+-------+ || value |------++-------+

date1date2变量的是对Date对象的引用,而不是它的副本。(所有对象都是这样工作的。)您可以将对象引用看作是在内存中查找对象的内存地址。(它实际是什么取决于实现。)

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

var n = 42;

搜索结果<前>+-----------++ n |+-----------+| value: 42 |+-----------+在<<p> (em> 理论。事实上,字符串"原语"会表现得好像那是真的,但实际上可能更像对象一样存储。没关系,字符串是不可变的,=====对于字符串原语比较它们的内容,所以我们不能真正区分它们,我们可以假装它们实际上包含在变量中。[只是真的让人困惑:JavaScript也有NumberString 对象,它们的行为就像对象])


下面是你的问题:

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

没有通用的"克隆";操作,所以答案因对象而异。有些对象不需要克隆,因为它们是不可变的(不能改变),所以不需要克隆(例如String对象)。

克隆日期很简单:

date2 = new Date(date1);

或者稍微更有效:

date2 = new Date(+date1);

(因为+告诉date1对象将自身转换为一个数字,然后Date构造函数使用这个数字。如果没有它,date1对象将被要求将自身转换为字符串,然后Date构造函数将解析该字符串。仍然有效,但通过数字进行优化是一种微观的——几乎可以肯定是不成熟的——并且可能会干扰引擎可能想要使用的任何隐藏优化。所以我就用date2 = new Date(date1);)

两个日期变量只是对内存中同一个日期对象的引用。所以你需要date2date1克隆。变化:

var date2 = date1;

:

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

JavaScript对日期*(以及所有非原语——var o = {}; var j = o; j.foo = 1; console.log(o.foo); //1)使用引用传递。另一方面,对于数字、字符串和布尔值(var o = 0; var j = o; j++; console.log(j); // 0),这是预期的行为。

如果你需要复制一个日期,你总是可以

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

date2是对date1的引用。

要达到预期的结果,请执行以下操作:

var date1 = new Date();
date1.setFullYear(2011, 6, 1); 
var date2 = new Date();
date2.setTime(date1.valueOf());

解决方案是创建第二个日期,使用相同的内部毫秒值,从第一个复制:

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

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

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

更多阅读:日期- MDN.

@SergeS的答案的变化,但Date()对象在js强制到数字,所以你不需要getTime():

// general case
var dateValueCopy = new Date(date1);

并以OP变量名重述:

var date2 = new Date(date1);

您需要创建date1的副本,目前date1date2引用相同的日期对象。

var date2 = new Date(date1.valueOf());

当你这样做的时候:

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

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