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.
精彩评论