开发者

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


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

date2 = new Date( date1 );


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


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


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.


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


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.


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


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

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


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜