You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
컴퓨터는 디스크에 있는 파일의 문자를 읽어서 어떤 동작을 할 수 있는 상태로 변경을 해야 한다.
컴퓨터가 코드의 동작을 수행하기 위해서 컴퓨터가 이해할 수 있는 0과 1로 이뤄진 코드를 변환하여 메모리에 저장을 한다.
컴퓨터의 CPU는 메모리에서 컴퓨터가 이해할 수 있는 실행 명령들을 처리한다.
호이스팅
자바스크립트 파일의 코드가 컴퓨터가 작동할 수 있는 0과 1의 코드로 변환이 되어 메모리에 올라갈 때, var, let, const 등에 의해 선언된 변수는 변수의 값을 저장하는 공간 영역을 만들게 된다. 메모리상에서의 변수가 값을 담을 수 있는 공간을 만드는 작업을 호이스팅이라고 한다.
변수가 자바스크립트의 값을 가질 수 있는 공간을 만들 때, 변수를 선언하고 변수에 초기화 되지 않았다면 (변수에 아무런 값을 넣지 않았다면) 자바스크립트는 var로 선언된 경우 변수의 초기 값으로 undefined를 할당하고, let이나 const로 변수가 선언된 경우에는 변수 공간만 만들고 아무런 값도 할당하지 않는 상태가 된다.
자바스크립트에서 변수에 아무런 값도 할당되지 않았는데 이 변수를 사용하는 경우에는 에러가 발생한다. 기본적으로 값이 할당되지 않은 경우 undefined 값으로 할당을 하는데, undefined 값조차 할당이 되지 않았다면, 변수가 메모리 상에서 공간을 확보하고 있어도 사용할 때 에러가 발생한다.
호이스팅의 예제
var의 경우
(function(){for(vari=1;i<=5;i++){console.log('previous value',varVar);varvarVar=i;console.log('in for',varVar);}console.log('out of for',varVar);})();
var로 선언된 변수는 함수 스코프를 가진다. 따라서 호이스팅은 함수 범위에서 이뤄진다. var로 호이스팅이 되면 var로 선언된 변수에 undefined가 할당이 된다.
따라서 for 문 안의 블록이 처음 실행 될 때 previous value undefined라는 값이 출력되는 것을 확인할 수 있다.
for문 안의 블록이 처음 실행 될 때 var varVar = i; 부분의 코드가 실행되지 않더라도 그 전에 이미 var로 선언된 변수를 사용할 수 있다. 이것은 이미 자바스크립트가 코드를 읽어서 메모리에 컴퓨터가 동작할 수 있는 형태의 로직을 올릴 때 변수의 공간을 메모리에 만들어 두었기 때문에 초기값이 할당되는 var varVar = i 부분이 실행되지 않더라도, 변수는 이미 함수 스코프 내에서 사용할 수 있는 상태가 된 것이다.
let의 경우
(function(){for(vari=1;i<=5;i++){console.log('previous value',letVar);letletVar=i;console.log('in for',letVar);}console.log('out of for',letVar);})();
let으로 선언된 변수는 블록 스코프를 가진다. 따라서 호이스팅은 블록 범위 내에서 이뤄진다. let으로 호이스팅이 되면 let으로 선언된 변수는 메모리상의 값을 넣을 수 있는 공간만을 만들어 두고, 변수에 값이 초기화 되지 않았다면 값은 할당되지 않는다. var로 선언된 변수가 undefined가 할당된 것과는 다르다.
따라서 for문 안의 블록이 처음 실행될 때 console.log('previous value', letVar); 부분의 코드는 실행되지 않는데, let으로 선언된 변수에 아무런 값도 할당되지 않았기 때문에 Uncaught ReferenceError: Cannot access 'letVar' before initialization라는 에러가 발생한다.
에러 메시지를 보면 letVar값에 접근을 할 수 없다는데 그 이유는 초기화 되기 전이라서 접근할 수 없다는 에러가 발생한다. 자바스크립트에서 에러가 나면 코드의 실행은 기본적으로 정지가 되는데 for문의 블록 안의 코드가 처음 실행될 때 console.log('previous value', letVar); 부분에서 에러가 나서 정지가 된다. 따라서 뒤의 코드는 실행되지 않는다.
하지만 뒤의 코드가 실행이 되지도 않았는데 '변수가 없습니다'라는 에러 메시지가 아니라 '초기화 되기 전이라서 접근할 수 없다는 에러'가 나타난 것은 이미 이 변수가 뒤에 선언되어 있다는 것을 자바스크립트가 알고 있다는 뜻이다. 자바스크립트가 이미 알고 있는 이유는 블록 스코프의 코드를 자바스크립트가 메모리상에서 컴퓨터가 동작할 수 있는 형태의 로직으로 변환해서 올릴 때 변수에 공간을 할당하는 작업을 하는 호이스팅을 하고, 호이스팅으로 인해서 let으로 선언된 변수가 있는 것은 알고 있지만, 초기화되기 전이라서 접근이 불가능하다는 에러가 나타나는 것이다.
let 뿐만 아니라 const도 동일하게 호이스팅을 한다. 블록 스코프 범위에서 호이스팅이 되고, 초기화되기 전에는 접근이 불가능한 값이다.
cosnt와 let의 차이
let은 재할당이 가능한 반면, const는 재할당이 불가능하다는 특징을 가지고 있다.
선언 한다는 것은 const 변수명, let 변수명의 부분에 해당한다. 그리고 초기화한다는 것은 const 변수명 = 값, let 변수명 = 값의 부분에 해당한다. 그리고 재할당이란 선언된 변수에 다른 값을 할당하는 것으로 변수명 = 값의 부분에 해당한다.
constVar = 're-assignment' 부분의 코드를 실행하면, Uncaught TypeError: Assignment to constant variable.라는 에러가 발생한다. 이는 const의 경우 재할당이 불가능하기 때문이다.
재할당을 하지 않더라도 값을 변경할 수 있다.
(function(){constconstVar={key: 'initialization'};constVar.key='re-assignment key of object';console.log(constVar);})();
위 코드를 실행하면 {key: 're-assignment key of object'}라는 값이 출력 된다. 오브젝트 내부의 key의 값이 바뀐 것을 확인할 수 있다. 하지만 이것은 변수 자체가 재할당 된 것이 아니라 변수 내의 값이 재할당 된 것이다.
(function(){constconstVar={key: 'initialization'};constVar={key: 're-assignment key of object'};console.log(constVar);})();
위 코드를 실행하면 변수 자체에 재할당을 하는 것이기 때문에 에러가 발생한다.
호이스팅을 하게 되면 변수에 값을 저장할 수 있는 공간을 만든다고 하였다. 그런데 변수에 오브젝트가 아닌 다른 값을 할당하는 경우에는 복사가 된다.
const변수=값;
자바스크립트는 값이라는 것을 만들고 값을 복사를 해서 호이스팅으로 만들어진 변수의 공간에 값을 넣는다. 변수가 할당된 값과 위 코드의 오른쪽에 있는 값은 복사되었기 때문에 동일한 원본이 아니다.
const변수=오브젝트;
하지만 오브젝트 변수에 할당을 했을 때는 위 코드의 오른쪽에서 만들어진 오브젝트를 가리키는 주소를 호이스팅으로 만들어진 변수의 공간에 넣는다. 따라서 변수에 접근을 하게 되면 주소를 따라서 오브젝트로 가라는 동작이 이뤄지기 때문에 동일한 원본에 접근하게 된다.
재할당이란 것은 변수를 다른 값으로 교체하는 작업을 할 수 있는 기능을 제공한다. 하지만 오브젝트 내부에 키를 추가 및 제거하거나 키의 값을 바꾸는 작업은 변수를 다른 것으로 바꾸지 않고 동일한 오브젝트 내부의 값을 바꾸는 것이다. 따라서 이것은 변수의 재할당과는 다른 개념이기 때문에 const로 선언되었더라도 오브젝트의 내부 값을 변경하는 것은 가능하다.