I noticed this situation in my code (unfortunately), and was able to duplicate it in my own JS file. So I have this code:
var date1 = new Date(); // today
var date2 = date1;
date2 = date2.setDate(date2.getDate() + 1);
// what is date1?
After this code executes, date1开发者_运维问答 is today's date + 1! This harkens back to my undergrad days when I learned about pointers, and I guess I'm a little rusty. Is that what's happening here? Obviously I've moved the assignment away from date1, and am only modifying date2, but date1 is being changed. Why is this the case?
Incidentally, after this code executes date2 is a long number like 1272123603911. I assume this is the number of seconds in the date, but shouldn't date2 still be a Date object? setDate() should return a Date object.
Classic case of Rerence Types vs. Value Types.
When the assignment operator works on primitive values (numbers, strings, Boolean, null, and undefined), a copy of the value is made. When the assignment operator works on JavaScript objects, references to the objects are copied.
Assignment by Value Versus Assignment by Reference
Therefore:
// creates a new Date object in memory with date1 as a Reference to its location
var date1 = new Date();
// date2 will now point to the same Object in memory as date1
var date2 = date1;
// Since both date1 and date2 point to the same object,
// modifying one changes the other
date2 = date2.setDate(date2.getDate() + 1);
As for the resulting value, you're correct. It's getting converted inside the expression to the number of seconds since Epoch.
Your variables date1
and date2
are pointing to the same object.
That's why the when you execute the setDate
on the date2
variable, you see the change on date1
, because actually the two variables point to the exact same object.
_____ ____________ |date1| --------->| new Date();| ¯¯¯¯¯ ¯¯¯¯¯^¯¯¯¯¯¯ _____ | |date2| ----------------- ¯¯¯¯¯
The setDate
method returns the valueOf
the Date
object after changing it, which is a numeric representation, milliseconds since 01 January, 1970 UTC until your date.
- both your variables reference the same object, and the
setDate()
call actually changes the object itself (in other words, it doesn't just clone the original and return the new one) - When you use a Date object in an expression it can end up being cast to a number, which (as you say) is the number of seconds since the epoch.
This code:
var date1 = new Date(); // today
var date2 = date1;
...creates one date object, which has two references to it. Since both variables point to the same object, any changes to the object are visible using either variable. They both point to the same thing. The thing stored in the variable is the reference to the object, not the actual object.
The best way to think about it (and indeed literally what's happening) is that variables contain values. Full stop. With primitives like (say) the number 5, the value held by the variable is the value. With object references, the value held by the variable is a reference to (pointer to) the object, not the actual object. For all we know, that reference is the number 77314 which is an index into some lookup table somewhere containing the actual object data. We don't know (or care), it's just a value that gets us to the object.
The rules for what happens with assignment, passing values into functions, etc., are identical in both situations — values are values. So:
var n1, n2;
n1 = 5; // n1 has the value 5
n2 = n1; // n2 now also has the value 5
And:
var d1, d2;
d1 = new Date(); // d1 has a value that references the new Date object
d2 = d1; // d2 now also has that value, which references that object
When you change the object's properties, it doesn't have any effect on the reference to the object. The object's properties belong to the object, not to the reference to the object. So since the two variables point to (refer to) the same thing, if you change that thing using one of the variables, you see the changes if you query the object using the other variable.
精彩评论