
1) 변수 선언 단계
변수 객체에 변수를 등록하여, 자바스크립트 엔진에게 변수의 존재를 알려주는 단계
var name;2) 초기화
변수 객체에 등록된 변수를 메모리에 할당한다.
변수는 암묵적으로undefined로 초기화된다.3) 할당
undefined로 초기화된 변수에 실제값을 할당한다.
name = ' 코드';🌱 선언과 할당을 동시에
var name = '코드';
✔ 변수를 "재선언"할 수 있다.
var message = "This"; var message = "That";✔ 값을 "재할당(변경)"할 수 있다.
var message = "This"; message = "That";✔ 선언만 하고 할당 안해도 상관 없으며, 그 때 값은 undefined가 된다
✔ 변수를 "재선언"하면 에러가 발생한다.
let message = "This"; let message = "That"; // SyntaxError: 'message' has already been declared✔ 값을 "재할당(변경)"할 수 있다.
let message; message = 'Hello!'; message = 'World!'; // 값이 변경되었습니다.✔ 선언만 하고 할당 안해도 상관 없으며, 그 때 값은 undefined가 된다
변화하지 않는 상수를 선언할 땐, const를 사용한다.
✔ 변수를 "재선언"하면 에러가 발생한다.
const message = "This"; const message = "That"; // SyntaxError: Identifier 'message' has already been declared✔ 값을 "재할당(변경)"할 수 없다.
const myBirthday = '18.04.1982'; myBirthday = '01.01.2001'; // error, can't reassign the constant!✔ 선언만 하고 할당 안하면 안 되며, 반드시 초기화된 상태여야 한다..!
🌱 변수 선언문이 코드의 최상단으로 이동되는 것처럼 느껴지는 현상
다른 언어에는 거의 없는 현상이다.
🌱 변수 선언 전에 해당 변수에 접근할 때에, 호이스팅에 의해서 그 변수는 undefined가 된다.
➡ var 변수는 접근이 가능하며 undefined이다.
➡ let, const는 호이스팅은 일어나지만 변수 선언 전에 접근하는 것을 막아주기 때문에 error가 발생된다.
console.log(name); // undefined
var name = '이름';
console.log(name); // 이름
console.log(suzy); // ReferenceError
let suzy = '수지';
console.log(jenny); // ReferenceError
const jenny = '제니';
모든 식별자(변수, 함수, 클래스 이름)가 유효한 범위이다.
스코프 내에서 식별자는 유일해야 하지만, 다른 스코프에는 같은 이름의 식별자를 사용할 수 있다.
코드의 가장 바깥 영역
전역 스코프에 선언된 변수는 '전역 변수'이다.
전역 변수는 어디에서든지 참조 가능하다.
함수 / 블록 스코프로 나뉜다.
지역 스코프에서 선언된 변수는 '지역 변수'이다.
자신의 지역, 그리고 하위 지역 스코프에서 유효하다.
함수 스코프
함수가 선언될 때 생성되는 스코프블록 스코프
if문, while문, for문, try-catch문내부의 스코프
var keyword는 함수레벨 스코프만 만들어 낸다. 즉, 함수레벨의 스코프만 지역 스코프로 인정한다.
var i = 999;
for (var i = 0; i<10; i++) {
console.log(i); // 0 부터 9 출력
}
console.log(`i in global scope: ${i}`) // 10
왜 for 문 안에서 i를 새로 선언했는데 왜 glboal scope의 i가 변경되지?
➡ var은 새로 scope가 생기는 경우는 함수를 선언했을 때 뿐이다!
즉, for loop이나 if, while문은 var 변수를 썼을 때 scope를 새로 만들어내지 않기 때문에 global 변수 값을 변경하게 될 수 있다.
let, const 키워드는 함수레벨, 블록레벨 스코프를 만들어낸다.
i = 999;
for (let i = 0; i<10; i++) {
console.log(i); // 0 ~ 9 출력
}
console.log(`i in global scope: ${i}`) // 999
let, const의 경우는 함수뿐 아니라 for, if, while 문등의 block level scope도 만들어 낸다..!
자바스크립트 엔진은 식별자를 찾을 때, 자신이 속한 스코프를 먼저 찾는다.
그곳에 식별자가 존재하지 않는다면 자바스크립트 엔진이 스코프 체인을 따라 올라가면서 (상위 스코프를 올라가면서) 식별자를 찾아 낸다.
Lexical Scope
선언된 위치가 '상위 스코프'를 정한다.dynamic scope
실행(호출)한 위치가 '상위 스코프'를 정한다.➡ 자바스크립트는 Lexical Scope이다..!
var numberThree = 3;
function functionOne() {
var numberThree = 100;
functionTwo();
}
function functionTwo() {
console.log(numberThree);
// 변수 numberThree를 global scope에서 가져올까 아니면 호출한 functionOne함수 내부 scope에서 가져올까
}
functionOne();
3이 출력된다. 즉 lexical scope의 개념에 따라, global scope에서 가져온다..!
만약 dynamic scope라면 호출된 위치에서, 즉 100이 될 것이다..!