1.
// var는 한번 선언된 변수를 다시 선언 할 수 있다.
var name = 'mike';
console.log(name); // mike
var name = "jane";
console.log(name) // jane
2.
// let은 한번 선언된 변수를 다시 선언 할 수 없다.
let name = 'mike';
console.log(name); // mike
let name = 'jane';
console.log(name); // error !
3.
// var는 선언하기 전에 사용할 수 있다.
// >> 호이스팅 이라 한다.
console.log(name); // undefined.
var name = 'mike';
4.
// var는 선언하기 전에 사용할 수 있다.
// 실제 작동 되는 원리는 아래와 같다.
// var로 선언한 모든 변수는, 코드가 실제로 이동 하지는 않지만,
// 최상위로 끌어 올려진것처럼 동작 한다.
// 이를, 호이스팅 이라 한다. (hoisting)
// 호이스팅 :
// 스코프 내부 어디서든 변수 선언은 최상위에 선언된 것 처럼 행동.
var name;
console.log(name); // undefined.
name = 'mike';
// 이때, console.log(name) 은 undefined 가 뜨게 된다.
// 선언은 호이스팅 되지만,
// 할당은 호이스팅 되지 않기 때문이다.
// var name; 만 최상위로 올려지고,
// name = 'mike' 는 이동 하지 않기 때문이다.
5.
// let 으로 선언된 것도 호이스팅은 된다. (const 도 호이스팅이 가능 하다)
// 하지만, 아래의 코드는 ReferenceError 에러가 발생 하게 된다.
// 할당을 하기 전까지는, 사용이 불가능 하다는 의미 이다.
console.log(name); // ReferenceError.
let name = 'mike';
let으로 선언한 변수를 사용 하려면,
반드시 값이 존재 해야 한다.
값이 없기 때문에, ReferenceError 가 발생 하는 것을 확인 할 수 있다.
만약 let 이 아니라, var 였으면, undefined 로 뜨게 된다.
[ 참고 ]
호이스팅이 되서,
let name; 은 상단으로 올라가게 되는 효과를 가지는데,
name = 'mike'
즉, 할당은 같이 호이스팅 되지 않는다.
분명, 선언과 할당을 동시에 하는 초기화 코드를 작성 했지만,
호이스팅은 선언부만 올라가고, 값을 초기화 해주는 부분은 올라 가지 않는다.
6.
// let 으로 선언된 것도 호이스팅은 된다. (const 도 호이스팅이 가능 하다)
// 하지만, 아래의 코드는 ReferenceError 에러가 발생 하게 된다.
// TDZ(Temporal Dead Zone) 라는 개념이 있다.
// 할당을 하기 전까지는, 사용이 불가능 하다는 의미 이다.
// ===== TDZ(Temporal Dead Zone) =====
// console.log(name);
// ===== TDZ(Temporal Dead Zone) =====
const name = 'mike'; // 함수 선언 및 초기화.
console.log(name); // 사용 OK.
// TDZ 의 목적
// 코드를 예측 가능 하게 하고, 잠재적인 에러를 방지 하기 위해서 이다.
TDZ(Temporal Dead Zone) 라는 개념이 있다.
TDZ는 변수가 선언되었지만 초기화되기 전까지의 구간을 의미 한다.
7.
let age = 30;
function showAge() {
console.log(age);
}
showAge();
// OK.
8.
let age = 30;
function showAge() {
console.log(age);
let age = 20;
}
showAge();
// 에러 발생.
// showAge() 함수 내부는 바깥의 영역과 별개의 영역 이다.
// 따라서, let으로 선언된 age 라는 변수는 별개의 스코프 이다.
// TDZ 이슈로 인해서, ReferenceError 가 발생 하게 된다.
호이스팅 개념 이슈 이다.
showAge() 함수 내부에 있는,
let age = 20; 이
호이스팅 개념에 의해서,
let age; 가 상단으로 올라가고,
age = 20; 할당부가 아래에 남게 된다.
근데,
변수 선언 및 초기화가 동시에 된 형태가 아니라,
let age;
console.log(age);
age = 20;
으로 되기 때문에, 값이 없어서 에러가 발생하는것이다.
위의 코드를 정상적으로 작동 시키려면 아래와 같이 수정 해야 한다.
let age = 30;
function showAge() {
let age = 20; // 변수 초기화
console.log(age); // 20 출력
}
showAge();
console.log(age); // 30 출력
그러면,
함수 내부의 age와 외부의 age가 서로 다른 변수가 되서,
코드가 정상적으로 작동 하게 된다.
9.
변수의 생성 과정
// 변수의 생성 과정
// 1. 선언 단계
// 2. 초기화 단계
// 3. 할당 단계
// 초기화와 할당의 차이점
// 초기화는 변수를 선언함과 동시에 값을 넣어 주는 것을 의미 한다.
// 예시)
// var test = 'test1234';
// 할당은 변수를 선언 하고 나서, 대입 연산자 (=) 를 통해 값을 넣어 주는 것을 의미 한다.
// 예시)
// var test;
// test = 'test1234';
// var은 선언과 초기화를 한번에 처리 한다.
// var
// 1. 선언 및 초기화 단계
// 2. 할당 단계
// 초기화 : undefined를 할당 해주는 단계를 의미 한다.
// let은 선언 단계와 초기화 단계가 분리 되어 처리 된다.
// let
// 1. 선언 단계
// 2. 초기화 단계
// 3. 할당 단계
// const는 선언, 초기화, 할당 단계를 한번에 싹 처리 한다.
// const
// 1. 선언 + 초기화 + 할당
// 예시)
let name;
name = 'mike';
var age;
age = 30;
const gender;
// Missing initializer in const declaration 에러.
// 선언 하면서 할당을 바로 안해서 발생 하는 에러.
gender = 'male';
10.
스코프 개념
// 스코프
// var : 함수 소코프 (function-scoped)
// let & const : 블록 스코프 (block-scoped)
// 함수, if 문, for 문, while 문, try/catch 문, .. 등등
// 예시
function add() {
// Block-level Scope (지역 변수)
}
let str = 'test';
if (str == 'test') {
// Block-level Scope (지역 변수)
}
for (let i = 0; i < 10; i++) {
// Block-level Scope (지역 변수)
}
// 예시 2
const age = 30;
if (age > 19) {
var txt = '성인';
}
console.log(txt); // 성인
// if 문 안에 선언 및 초기화 된 var txt는 if 문 밖에서도 사용이 가능 하다.
// 예시 3
const str2 = 'test';
if (str2 == 'test') {
const str3 = 'test02';
}
// console.log(str3);
// 변수 str3은 if 문 내부의 지역 변수로 선언 및 초기화 되었기 때문에,
// if 문 밖에서 사용이 불가능 하다.
// Block-level Scope
// 예시 4
// 하지만, var도 함수 내부에서 선언 되면 외부 에서 사용이 불가능 하게 된다.
// var는 if 문, for 문, try-catch 문, .. 등에서 사용 되면,
// 외부에서도 사용이 가능 하지만,
// 유일하게 "함수" 내부에서 선언되면,
// var, let, const 변수 모두, 외부에서 사용이 불가능 하다.
function add(num1, num2) {
var result = num1 + num2;
}
console.log(result);
add(2, 3);
// 변수 선언 뿐만 아니라, 함수 선언도 호이스팅이 된다.
// 그래서, add(2,3); 이 메모리에 올려지게 되서,
// 실제로 코드상 function add(num1, num2) 보다 아래에 있더라도,
// 동작 할 수 있게 된다.
var는 if문, for문, try-catch 문, .. 등에서 사용되도,
외부에서 사용이 가능 하지만,
유일하게 "함수" 내부에서 선언되면,
제 아무리 var 이여도,
함수 외부에서 사용이 불가능 하다.
result가 선언조차도 되어 있지 않아서 발생하는 에러 이다.
11.
정리
// 결론
// var 를 사용 하는것 보다,
// let과 const를 사용 하는것을 지향 해야 한다.
// 코드를 예측 가능 하게 하고, 잠재적인 에러를 방지 하기 위해서 이다.
// why ?
// TDZ == Temporal Dead Zone 개념이 적용 되기 때문 이다.
// var 변수의 단점
// 1) 중복 선언으로 인해 예기치 못한 값이 반환 될 수 있다.
// 2) 함수가 아닌 다른 블록 스코프 에서 선언된 변수는
// 모두 전역 변수로 취급 되어 예기치 못한 할당이 일어날 수 있다.
// 3) 선언 전에 변수를 참조하면 undefined 가 될 수 있다.
// 위와 같이 3가지 문제가 발생할 수 있으므로,
// var 변수를 사용하는 것을 지양하고,
// let & const 변수를 사용하는 것을 지향 해야 한다.
// 상수를 사용 해야 한다면, const 를 사용 하면 된다.
// Java의 final 키워드와 유사한 역할 이라고 생각 하면 된다.
'자바스크립트 (JavaScript) > 이론' 카테고리의 다른 글
[ JS 데이터 ] 참조형 - Array (0) | 2023.10.30 |
---|---|
[ JS 데이터 ] 원시형 - Boolean, null, undefined (0) | 2023.10.30 |
[ JS 데이터 ] 원시형 - String, Number (1) | 2023.10.29 |
생성자 함수 개념 (0) | 2023.08.27 |
변수, 호이스팅, TDZ (Temporal Dead Zone) 요약 (0) | 2023.08.20 |