자바 스크립트 포인터 / 참조 광기. 누군가 이것을 설명 할 수 있습니까?
자바 스크립트는 객체를 참조로 전달합니다. 이것은 완벽합니다. 그러나 일단 이러한 객체를 조작하기 시작하면 모든 것이 직관적이지 않은 방식으로 작동합니다. 예를 들어 보겠습니다.
var a, b;
a = {}
b = a;
a['one'] = {};
console.log( JSON.stringify(a) );
// outputs: {"one":{}}
console.log( JSON.stringify(b) );
// outputs: {"one":{}}
이제 b포인터가 a있으므로 항목을 할당 a하면에 영향을 미칠 것으로 예상 되기 때문에 이것은 모두 훌륭하고 좋습니다 b.
하지만 이렇게하면 :
a = a['one'];
console.log( JSON.stringify(a) );
// outputs: {}
console.log( JSON.stringify(b) );
// outputs: {"one":{}}
이것은 저에게 놀랍습니다. 나는 기대 a와 b여전히 동일하게 (그리고 수 {}있기 때문에 a['one']이전에 설정 {}과 a에 설정 a['one']).
그러나 그것은 사실이 아닙니다. 새로운 것에 할당되었을 때에 a대한 참조를 잃어버린 것처럼 보이지만 참조 를 잃어 버리기 전에 설정된 값은 유지합니다 .bbaab
하지만 이렇게하면 :
a['two'] = 2;
console.log( JSON.stringify(a) );
// outputs: {"two":2}
console.log( JSON.stringify(b) );
// outputs: {"one":{"two":2}}
뭐? a에 대한 참조를 분명히 잃어 버렸지 b만 b여전히에 대한 참조가있는 것 같습니다 a.
빈 개체 {}가 메모리의 특정 위치를 가리 키므로이를 참조하는 모든 변수가 이제 동일한 위치를 가리키고 있습니까?
이것에 대해 확고하게 이해하는 사람이 나에게 설명 할 수 있습니까?
한 줄씩 예제를 따르십시오.
a = {}
a 이제 새 개체를 참조합니다.
b = a;
b이제 참조하는 동일한 개체를 a참조합니다. 참조하지 않습니다 a.
a['one'] = {};
이제 새 개체에는 'one'다른 새 개체를 참조 하는 인덱스 가 있습니다.
당신이 할 때
a = a['one'];
당신은 a참조하도록 설정 하고 a['one']있는데, 그것은 당신이 만들었을 때 당신이 만든 새로운 객체 a['one'] = {}입니다. b으로 만든 개체를 계속 참조합니다 a = {}.
는를 a참조 하지 않기 b때문에 "에 대한 참조를 잃었습니다 "라고 말하면 문제를 혼동하게됩니다 . 그 반대의 경우도 마찬가지입니다. 및 참조 객체 , 그리고 그들은 다른 객체를 참조 할 수있다. 이렇게 :abab
를 사용 a = {}; b = a하면
a
\
\
{ }
/
/
b
그런 다음 a['one'] = {}당신 과 함께
a
\
\
{ one: { } }
/
/
b
그런 다음 a = a['one']당신 과 함께
a - - - -
\
{ one: { } }
/
/
b
: P 당신은 꼼꼼한 세부 사항으로 내려 가고 있으며 당신이 마지막까지 더 현명해질 것이기 때문에 당신이 물어서 기쁩니다.
나는 그것이 당신이 혼란스러워하는 곳이라고 생각하기 때문에 그것을 포인터로 보지 마십시오. 오히려 힙 (또는 원할 경우 "메모리") 및 기호 테이블의 관점에서 생각하십시오.
코드의 처음 몇 줄부터 시작하겠습니다.
var a, b;
a = {}
b = a;
여기서 수행 한 작업은 힙에 하나의 개체와 기호 테이블에 두 개의 기호를 만드는 것입니다. 다음과 같이 보입니다.
기호 테이블 :
+--------+-----------------+
| Symbol | Memory Location |
+--------+-----------------+
| a | 0x400000 |
+--------+-----------------+
| b | 0x400000 |
+--------+-----------------+
힙 :
+----------+-----------------+
| Location | Value |
+----------+-----------------+
| 0x400000 | <object val 1> |
+----------+-----------------+
.
흥미로운 점은 다음과 같습니다. 객체에는 고유 한 "기호 테이블"이 있습니다 (일반적으로 이들은 해시 테이블 일 뿐이지 만 기호 테이블이라고 부르면 더 명확 해집니다).
이제 다음 명령문 다음에 고려해야 할 세 가지 사항이 있습니다. 글로벌 기호 테이블, <object val 1>의 기호 테이블 및 힙입니다.
다음 행을 실행하십시오.
a['one'] = {}
이제 다음과 같이 보입니다.
글로벌 심볼 테이블 :
+--------+-----------------+
| Symbol | Memory Location |
+--------+-----------------+
| a | 0x400000 |
+--------+-----------------+
| b | 0x400000 |
+--------+-----------------+
<object val 1>의 심볼 테이블
+--------+-----------------+
| Symbol | Memory Location |
+--------+-----------------+
| one | 0x400004 |
+--------+-----------------+
힙 :
+----------+-----------------+
| Location | Value |
+----------+-----------------+
| 0x400000 | <object val 1> |
+----------+-----------------+
| 0x400004 | <object val 2> | <---we created a new object on the heap
+----------+-----------------+
.
이제 다음 코드를 실행했습니다.
a = a['one'];
이것은 사소한 변화처럼 보일 것입니다. 결과는 다음과 같습니다.
글로벌 심볼 테이블 :
+--------+-----------------+
| Symbol | Memory Location |
+--------+-----------------+
| a | 0x400004 |
+--------+-----------------+
| b | 0x400000 |
+--------+-----------------+
<object val 1>의 심볼 테이블
+--------+-----------------+
| Symbol | Memory Location |
+--------+-----------------+
| one | 0x400004 |
+--------+-----------------+
힙 :
+----------+-----------------+
| Location | Value |
+----------+-----------------+
| 0x400000 | <object val 1> |
+----------+-----------------+
| 0x400004 | <object val 2> |
+----------+-----------------+
.
힙에 대한 메모리 위치를 따라 가면 출력을 얻은 이유가 분명해질 것입니다.
이제는 다음을 수행하고 있기 때문에 상황이 더욱 흥미로워집니다.
a['two'] = 2;
자,이 단계를 단계별로 진행하겠습니다.
a0x400004포함 하는 메모리 위치 를 가리 킵니다.<object val 2><object val 2>빈 객체이므로 심볼 테이블이 비어 있습니다.- 이 줄을 실행하여
<object val 2>'의 기호 테이블에 'two '변수를 추가 합니다.
아직이 다이어그램을 보는 데 지치지 않았다면 그렇게 될 것입니다. 이제 상황은 다음과 같습니다.
글로벌 심볼 테이블 :
+--------+-----------------+
| Symbol | Memory Location |
+--------+-----------------+
| a | 0x400004 |
+--------+-----------------+
| b | 0x400000 |
+--------+-----------------+
<object val 1>의 심볼 테이블
+--------+-----------------+
| Symbol | Memory Location |
+--------+-----------------+
| one | 0x400004 |
+--------+-----------------+
<object val 2>의 심볼 테이블
+--------+-----------------+
| Symbol | Memory Location |
+--------+-----------------+
| two | 0x400008 |
+--------+-----------------+
힙 :
+----------+-----------------+
| Location | Value |
+----------+-----------------+
| 0x400000 | <object val 1> |
+----------+-----------------+
| 0x400004 | <object val 2> |
+----------+-----------------+
| 0x400008 | 2 (literal val) | <-- yes, even integers are stored on the heap
+----------+-----------------+ in JavaScript.
.
부지런히 시간을내어 메모리 위치를 추적하면 브라우저가 올바른 출력을 표시하는 것을 볼 수 있습니다.
Think of the anonymous object as itself having a name:
a = {}; // The variable "a" now points to (holds) an anonymous object.
b = a; // "b" points to the same anonymous object held by "a".
a = 123; // "a" now holds some other value.
b; // "b" still holds the anonymous object.
The key is to remember that variables hold references to objects, not references to other variables. And the same object may be referred to by any number of variables.
Objects in Javascript can exist by themselves without needing a name. For example:
{}
is a new instance of a dictionary object.
a = {};
creates a new dictionary object and makes a refer to it. Now
b = a;
makes b refer to the same underlying object. You can then make a point somewhere else:
a = "hi";
and b still points to the same dictionary object it did before. The behaviour of b is unrelated to how you change what a points to.
As far as i know you overwrited a so i guess the engine saves it in another memory space, whereas b still pointing to the old a's memory address (which somehow doesn't get destroyed).
'Nice programing' 카테고리의 다른 글
| Symfony 레이아웃에서 _locale 변수를 얻는 방법은 무엇입니까? (0) | 2020.11.25 |
|---|---|
| WPF의 명령을 컨트롤의 두 번 클릭 이벤트 처리기에 바인딩하는 방법은 무엇입니까? (0) | 2020.11.25 |
| html에서 UL 또는 OL을 언제 사용합니까? (0) | 2020.11.25 |
| PIP 설치에서 libffi를 인식하더라도 ffi.h를 찾을 수 없습니다. (0) | 2020.11.25 |
| PHP 내에서 .sql 파일로드 (0) | 2020.11.25 |