railOne
railOne

Reputation: 965

Javascript date variable assignment

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);

Upvotes: 19

Views: 43956

Answers (9)

yzorg
yzorg

Reputation: 4480

Variation of @SergeS's answer, but Date() objects in js coerce to number, so you don't need getTime():

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

And restated with OP variable names:

var date2 = new Date(date1);

Upvotes: 1

Hunter McMillen
Hunter McMillen

Reputation: 61540

When you do this:

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

You create a Date object on the first line, but the second line does not create another Date object, it only points or references the Date object that was already created. This is a common feature in many object oriented programming languages.

Upvotes: 0

Matt Ball
Matt Ball

Reputation: 359966

The solution is to create a second date that uses the same internal millisecond value, copied from the first:

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

Now you've got two distinct date instances that you can manipulate independently of one another.

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)

More reading: Date – MDN.

Upvotes: 2

T.J. Crowder
T.J. Crowder

Reputation: 1075239

When you do this:

date2=date1;

...you're not creating a new Date object, you're just pointing to the date object from two separate variables. There's only one object, so naturally any changes you make to it are apparent regardless of which variable you look through.

Let's throw some ASCII-art at it:

date1 = new Date();

That gives us:

+-------+
+ date1 +
+-------+                 +---------------+
| value |---------------->| a Date object |
+-------+                 +---------------+

Now when you do:

date2=date1;

We have

+-------+
+ date1 |
+-------+
| value |------+
+-------+      |          +---------------+
               +--------->| a Date object |
               |          +---------------+
+-------+      |
+ date2 |      |
+-------+      |
| value |------+
+-------+

The value of the date1 and date2 variables is a reference to the Date object, not a copy of it. (All objects work this way.) You can think of an object reference as like a memory address of where to find the object in memory. (What it actually is depends on the implementation.)

This is different from primitives, where the value of the variable actually contains the primitive's data, e.g.:

var n = 42;

Results in

+-----------+
+     n     |
+-----------+
| value: 42 |
+-----------+

(In theory. In fact, string "primitives" will behave as though that's true, but in reality probably are stored more like objects. Doesn't matter, strings are immutable and == and === for string primitives compares their content, so we can't really tell the difference and we can pretend that they're actually contained by the variable. [Just to really be confusing: JavaScript also has Number and String objects, which behave like objects.])


Re your question below:

In the interim, what is the most efficient way to create a second javascript object identical to a preexisting one?

There is no generic "clone" operation for JavaScript objects, so the answer varies by object. Some objects you don't need to clone, because they're immutable (can't be changed) and so don't need cloning (String objects, for instance).

To clone a date, it's easy:

date2 = new Date(date1);

Or the slightly more efficient:

date2 = new Date(+date1);

(Because the + tells the date1 object to convert itself to a number, and then the Date constructor uses that number. Without it, the date1 object would be asked to convert itself to a string, and then the Date constructor would parse that string. Still works, but going via the number is a micro- and almost certainly premature optimization — and one that might interfere with any hidden optimization an engine might want to use. So I'd just go with date2 = new Date(date1);.)

Upvotes: 8

SergeS
SergeS

Reputation: 11779

Date is object , so it is assigned as reference - simple approach is

date2 = new Date( date1 );

Upvotes: 32

cwallenpoole
cwallenpoole

Reputation: 82058

JavaScript uses pass by reference for Dates* (as well as all non-primitives -- var o = {}; var j = o; j.foo = 1; console.log(o.foo); //1. On the other hand, for Numbers, Strings, and Booleans var o = 0; var j = o; j++; console.log(j); // 0), so that is expected behavior.

If you need to copy a date you can always

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

* Please see comments to understand why this is not entirely correct.

Upvotes: 2

Guest
Guest

Reputation: 76

date2 It's a reference to date1.

To achieve the expected results, do the following:

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

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

Upvotes: 1

Alex K.
Alex K.

Reputation: 175926

You need to create a copy of date1, currently date1 and date2 refer to the same date object.

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

Upvotes: 0

davin
davin

Reputation: 45555

Both date variables are just references to the same date object in memory. So you need date2 to be a clone of date1. Change:

var date2 = date1;

to this:

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

Upvotes: 2

Related Questions