2010-04-23 4 views
1

내 코드에서이 상황을 발견했으며 (불행히도) 내 JS 파일에서이 상황을 복제 할 수있었습니다. 그래서 나는이 코드를 가지고 : JavaScript 포인터 및 날짜

var date1 = new Date(); // today 
var date2 = date1; 

date2 = date2.setDate(date2.getDate() + 1); 
// what is date1? 

이 코드가 실행 된 후

, 날짜 1 오늘 날짜 + 1입니다! 이것은 포인터에 대해 배웠을 때 학창 시절로 돌아 왔고, 나는 녹슨 것 같아요. 그게 여기서 일어나는거야? 분명히 date1에서 과제를 옮기고 date2 만 수정하고 있지만 date1은 변경 중입니다. 왜 이런 경우입니까?

덧붙여 말하면,이 코드가 실행 된 후 date2는 1272123603911과 같은 긴 숫자입니다.이 날짜는 초로 간주되지만 date2는 여전히 Date 객체가 아니어야합니다. setDate()는 Date 객체를 반환해야합니다.

답변

4

레어 런스 유형 대 값 유형의 전형적인 경우.

할당 연산자 프리미티브 값 (숫자, 문자열 부울 널 및 정의) 값의 복사본 작동된다. 할당 연산자가 JavaScript 개체에서 작동하면 개체에 대한 참조가 복사됩니다.

따라서

Assignment by Value Versus Assignment by Reference

: 결과 값에 관해서는

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

, 당신이 맞아요. 표현식 안에서 Epoch 이후로 초 단위로 변환됩니다.

+0

좋은 답변이지만, 나에게 이것이 무슨 일이 일어나고 있는지의 단순함을 완전히 모호하게했기 때문에이 "과제물 할당"용어가 마음에 들지 않았습니다. Javascript (및 Java)에서 변수는 값을 보유합니다. 그게 전부 야. 오브젝트의 경우, 변수에 의해 유지 된 * value *는 오브젝트에 대한 포인터 (포인터)에 대한 참조이지만, 여전히 값이므로 아무것도 일어나지 않습니다. 'o1 = o2'를하면, 특별한 경우는 없지만'o2'의 값은'o1'에 들어갑니다. 문제의 값이 객체에 대한 참조라는 것입니다. –

+0

그렇다면 date1의 가치를 보존하고 싶다면 무엇을해야할까요? date2를 새 객체로 만든 다음 date1을 할당합니다. 여기에서 어떻게 진행해야할지 모르겠다. –

1
  • 모두 당신의 변수는 같은 객체를 참조하고, setDate() 호출은 실제로 (즉 그냥 새 원본을 복제하고 반환하지 않습니다) 개체 자체를 변경하면 날짜를 사용할 때
  • 을 표현식에있는 객체로 숫자에 캐스트 될 수 있습니다. (말한대로) 그 시대 이후의 초 수입니다.
+0

두 번째 부분에 대답 해 주신데 감사합니다. 내가 날짜를 전진하려고 할 때 date2를 날짜 객체로 유지하도록 추천 하시겠습니까? 위의 예에서 date2는 날짜 개체가되고 내일은 날짜가됩니다. –

+0

다음과 같이 날짜 객체를 복사 할 수 있습니다 :'var dateCopy = new Date (otherDate.getTime());'그런 다음 원하는 경우 두 번째 세트에서'setDate()'를 호출 할 수 있습니다. – Pointy

1

이 코드는 :

var date1 = new Date(); // today 
var date2 = date1; 

... 그것은 두 개의 참조가 하나 날짜 객체를 생성한다. 두 변수가 동일한 객체를 가리키기 때문에 두 변수를 사용하면 객체에 대한 모든 변경 내용을 볼 수 있습니다. 그들은 둘 다 똑같은 것을 지적합니다. 변수에 저장된 것은 실제 객체가 아니라 객체에 대한 참조입니다.

그것에 대해 생각하는 가장 좋은 방법은 실제로 변수가 값을 포함한다는 것입니다. 마침표. 번호 5와 같은 프리미티브 (primitive)를 사용하면 변수가 보유한 값이 값이됩니다. 객체 참조에서 변수가 보유하는 값은 실제 객체가 아니라 객체에 대한 참조입니다. 우리가 알고있는 한, 그 참조는 실제 객체 데이터를 포함하는 어딘가의 룩업 테이블에 대한 인덱스 인 숫자 77314입니다. 우리는 (또는 관심)을 모르지만, 그것은 우리를 대상으로 가져 오는 가치입니다.

할당에서 발생하는 값, 함수에 값 전달 등의 규칙은 두 상황에서 동일합니다.   — 값은 값입니다.그래서 :

var n1, n2; 

n1 = 5; // n1 has the value 5 
n2 = n1; // n2 now also has the value 5 

그리고 :

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 

당신이 개체의 속성을 변경

, 그것은 개체에 대한 참조에 영향을주지 않습니다. 객체의 속성은 객체 참조가 아니라 객체에 속합니다. 따라서 두 변수가 동일한 것을 가리키고 (참조), 변수 중 하나를 사용하여 그 변수를 변경하면 다른 변수를 사용하여 오브젝트를 조회하면 변경 사항이 표시됩니다.

3

변수 date1date2이 동일한 개체를 가리키고 있습니다.

date2 변수에서 setDate을 실행하면 date1에 대한 변경 사항이 표시됩니다. 실제로 두 변수가 정확히 동일한 개체를 가리 키기 때문입니다.

 
    _____    ____________ 
    |date1| --------->| new Date();| 
    ¯¯¯¯¯    ¯¯¯¯¯^¯¯¯¯¯¯ 
    _____     | 
    |date2| ----------------- 
    ¯¯¯¯¯ 

setDate 방법은 숫자 표현을 변경 한 후 valueOfDate 객체를 반환 01 월부터 1970 UTC 날짜까지 밀리 초.

+0

+1 그림은 천 단어의 가치가 있습니다. –