개발자
let a = 1, let b = 2 일 때 a===b가 true인 이유가 다음과 같은 과정이라고 이해했습니다. 1. let a =1;를 선언함 2. 빈 공간의 메모리에 변수 명(식별자)a와 변수 값이 undefined로 할당됨 3. 원시 값 1를 저장하기 위해 메모리의 새로운 공간에 메모리주소 #001(예로 듦)과 원시 값인 1이 저장됨. 4. 처음에 만든 a라는 변수 명을 가진 메모리의 변수 값이 undefined에서 원시 값 1의 메모리 주소인 #001로 다시 저장됨. 5. 즉 a = #001가 됨. 6. 이때 let b = 1;을 선언함 7. 위의 과정을 반복해야하지만 JS 엔진의 메모리 최적화를 위해 같은 원시 값을 공유할 때는 새로 메모리를 생성하지 않고 #001를 참조함 8. 따라서 a = #001이고, b = #001이기 때문에 a===b가 true 근데 왜 참조 타입인 배열은 false인가요? 위의 과정과 어느 부분이 달라서 그런지 궁금합니다.
답변 2
인기 답변
질문의 핵심은 이거 같습니다 'number type을 할당할 때 실제 값이 아닌 메모리 주소가 할당될 것이다' 이것을 검증하고 싶은신거 같은데 직접 검증해 보시죠 1. 터미널을 열어서 "node --allow-natives-syntax" 라고 입력하면 REPL이 실행됩니다 2. let a = 1; 를 입력하고 엔터 3. %DebugPrint(a) ; 를 입력하고 엔터 위와 같이 입력하면 변수 a에 대한 정보가 출력됩니다. 그 결과 DebugPrint: Smi: 0x1 (1) 위와 같이 뜨는데 하나씩 해석해보면 Smi : 데이터 타입입니다. Small Integer의 줄임말입니다. 0x1 : 16진수로 표현된 변수 값입니다 (1) : 10진수로 표현된 변수 값입니다 결론은 a값인 1이 직접 할당되었고 1이 말씀하신 "원시 값 1의 메모리 주소가 저장"되는 일은 없습니다 (메모리 주소를 저장하고 있으면 메모리 주소가 출력됩니다) 다만 문자열의 경우는 질문자님이 말씀하신 프로세스와 비슷하게 작동합니다 const a = "hello world" 위의 식에서 원시 값 "hello world"는 constant pool이라는 곳에 저장되는데 이미 "hello world"값이 있다면 해당 메모리 주소를 포인팅합니다 이후 "hello world"를 몇번을 선언하던 관계없이 동일한 메모리 주소를 포인팅하므로 말씀하신 대로 메모리를 절약할 수 있게 됩니다 상세는 https://levelup.gitconnected.com/bytefish-vs-new-string-bytefish-what-is-the-difference-a795f6a7a08b 여기 참조하세요 다만 위의 설명은 v8기준이라 다른 엔진의 세부 구현은 다를 수 있습니다 마지막으로 질문하신 "근데 왜 참조 타입인 배열은 false인가요? " -> 객체를 생성할 때는 이미 같은 값이 있는지 체크하는 과정이 없습니다. 무조건 새로 생성합니다 배열도 객체이므로 무조건 새로 생성합니다
js에서 원시타입은 값을 직접 저장하고있습니다. 그리고 똑같은 값을 할당한다고 해도 기존값을 참조하지 않습니다. 때문에 a=1, b=1 이고, 비교하면 true가 나오게됩니다. 참조 타입도 기존값을 참조하지 않기는 마찬가지 입니다. 하지만 참조타입은 변수에 주소값을 저장합니다 let a =#001 {#001: [1,2,3]} , let b=#002 {#002: [1,2,3]} 이기 때문에 #001 과 #002 를 비교해서 false가 나오는 것입니다. 혹시 설명이 부족해서 이해가 잘 안되신다면 다시 정리해 드릴게요
윤성
작성자
학생 • 2023년 06월 17일
감사합니다! 참조 타입에 대해서는 이해가 되었습니다! 다만 궁금한 점이 있는데 let a= 1; let b= 1; 일 때 a===b가 true인 이유를 저는 아래와 같이 생각했는데 잘못됐을까요? 1. let a= 1;을 선언함 2. 메모리의 남은 공간에 변수명(식별자)a와 변수 값을 undefined로 초기화함 3. 원시 타입인 1을 저장하기 위해 콜스택(원시 타입의 데이터는 콜스택에 저장됨)에 메모리 주소 #0001(예로 듦)와 원시 값 1이 저장됨. 4.undefined로 초기화된 변수 값이 #0001로 다시 저장됨. 5. let b =1; 을 선언함 6.메모리의 남은 공간에 변수명(식별자)b와 변수 값을 undefined로 초기화함 7. 이 때 1이라는 값이 메모리에 이미 저장되어있다면 새로운 메모리를 확보하여 1을 다시 메모리에 생성하는 것이 아닌 원래 1이 저장되어있던 메모리 주소 즉, #0001를 가져옴 8. undefined로 할당되었던 b의 변수 값에 #0001을 저장함 9. 결국 a===b는 a의 값 즉, #0001과 b의 값 즉,#0001이 같기 때문에 true를 반환함.
뱀부
웹 프론트엔드 개발자 • 2023년 06월 17일
3. 원시타입의 경우 콜스택에 주소값이 아닌 값 자체가 저장됨 4. 때문에 a 엔 주소값(#0001) 이 아닌 1이 저장됨 7. 원시타입의 경우 크기가 정해져있어 따로 메모리를 확보할 필요가 없음. 8. 3,4와 마찬가지로 b에 1을 직접 저장 9. a=1, b=1 이므로 a===b 은 1===1 이기 때문에 true 반환 으로 정정해드리겠습니다. 밑에 이국범님이 자세하게 설명해주셨으니 저걸 읽어보심 될것같네요
지금 가입하면 모든 질문의 답변을 볼 수 있어요!
현직자들의 명쾌한 답변을 얻을 수 있어요.
이미 회원이신가요?
지금 가입하면 모든 질문의 답변을 볼 수 있어요!