01
var의 문제점
01. 변수 중복 선언 허용
var x = 1;
var y = 2;
// 변수 x 중복선언
var x = 100;
var y = 1;
console.log(x); // 100
console.log(y); // 1
- 위 코드와 같이 변수 x와 y를 중복선언이나 재할당을 해도 에러가 없이 작동을 합니다.
- 마지막에 할당된 값이 최종으로 변수의 값으로 저장됩니다.
02. 함수 레벨 스코프
var는 block scope가 아닌 function scope단위 변수입니다.
function counter(){
var i = 10;
console.log(i); // 10
for(var i = 0; i < 5; i++){
console.log(i); // 0 1 2 3 4
}
console.log(i); // 5
}
counter();
- 위 코드에서 for문 안에서 var 키워드로 선언한 변수 i는 의도하지 않았더라도 전역변수가 됩니다.
- 이렇게 전역으로 선언된 var는 함수 내부에 선언해 놓은 것과 달리 프로그램이 종료되기 전까지 계속 살아있게 됩니다.
- 이후에 어떤 동작을 일으킬지 예측하기가 더더욱 힘들어질수있습니다.
블록스코프(block scope) vs 함수스코프(function scope)
1. 스코프(scope) 란?
- 함수가 실행될 때 함수 내에서 변수에 접근할 수 있는 범위를 나타내는 용어입니다.
- 함수 실행컨텍스트 내부의 변수 환경
2. 함수스코프(function scope)
- 자바스크립트는 함수를 단위로 Scope를 구분합니다.
즉, 같은 함수 안에서 선언된 변수들은 같은 레벨의 Scope를 가지게 됩니다.
각각의 함수는 독립적인 Scope를 가지게 되어 다른 함수의 Scope에 접근을 할 수 없습니다.
if (true) {
var name = "Kim";
}
console.log(name); // Kim
3. 블록스코프(block scope)
- 블록스코프는 말 그래도 블록 {}이 생성될 때마다 새로운 Scope가 형성되는 것을 의미합니다.
( 우리가 많이 보는 if문, switch문, for, while문 등입니다.)
if (true) {
var name = "Kim";
let likes = "Coding";
const lang = "Javascript";
console.log(name); // 'Kim'
console.log(likes); // 'Coding'
console.log(lang); // 'Javascript'
}
console.log(name); // 'Kim'
console.log(likes); // Uncaught ReferenceError
console.log(lang); // Uncaught ReferenceError
var는 function scope라서 함수 범위 내부에서 접근할 수 있지만 외부에서는 접근 할 수 없다.
위코드에서는 같은 함수 범위 내부라 name을 호출하면 'Kim'이 출력됩니다.
let과 const는 block scope라서 블록 스코프(if문) 외부에서 변수에 접근하기 때문에 참조 오류(ReferenceError)가 발생합니다.
03. 변수 호이스팅
console.log(today); // undefined
var today = 'Wed';
console.log(today); // Wed
- var는 변수 생성 시에 생성된 변수를 맨 위로 올리는 호이스팅(Hoisting)을 진행합니다.
- 이는 코드 초반부에 변수를 선언해 놓은 것과 같은 효과가 나타납니다.
var today = 'Wed'
console.log(today)
var weather = 'rain'
console.log(weather)
- 위 코드처럼 변수를 선언하게 된다면
var today;
var weather;
today = 'Wed';
console.log(today); // Wed
weather = 'rain';
console.log(weather); // rain
- 호이스팅이 진행되면서 위코드처럼 작성한 것같이 됩니다.
//이전의 선언과 초기화가 실행됩니다.
console.log(today); // undefinded
var today;
console.log(today); // undefinded
//할당이 진행됩니다.
today = 'Wed';
console.log(today); // Wed
- 변수 선언문 이전에 변수를 참조하는 것은 에러를 발생시키진 않지만 가독성을 떨어트리고 오류를 발생시킬 여지를 남길 수 있습니다.
let
let은 var와 가장 유사합니다.
01. 변수 중복 선언 금지
console.log(y); // ReferenceError
let y = 456;
console.log(y); // 456
y = 123;
console.log(y); // 123
let y = 456;
console.log(y); // SyntaxError
- 위 코드처럼 한 번 할당된 값을 언제든지 변경할 수 있습니다.
- var처럼 같은 이름의 변수를 중복선언한다던가, 나중에 선언한 변수의 이름을 미리 쓸 수 있다던가 라는 문제는 없습니다.
02. 블록 레벨 스코프
let은 block scope단위 변수입니다.
let foo = 1; // 전역 변수
{
let foo = 2; // 지역 변수
let bar = 3; // 지역 변수
console.log(foo); // 2
console.log(bar); // 3
}
console.log(foo); // 1
console.log(bar); //ReferenceError
- block scope 안에서 선언된 foo변수와 bar변수는 {} 내부에서만 호출될 수 있습니다.
03. 변수 호이스팅
let으로 선언한 변수는 변수 호이스팅이 발생하지 않는 것처럼 동작합니다.
console.log(num); //ReferenceError
let num = 2;
- 위 코드처럼 변수를 선언하기 이전에 참조하면 ReferenceError 가 발생합니다.
//런타임 이전 선언이 실행됩니다. 초기화는 되지않았습니다.
console.log(today); // ReferenceError
//변수선언에서 초기화가 실행됩니다.
let today;
console.log(today); // undefinded
//할당이 진행됩니다.
today = 'Wed';
console.log(today); // Wed
- let이 호이스팅이 아예 발생하지 않는 건 아닙니다.
위의 예제에서 호이스팅이 되지 않았다면 foo는 전역변수인 1 값을 출력했었겠지만,let foo = 1; // 전역 변수 { console.log(foo); // ReferenceError let foo = 2; // 지역 변수 }
지역변수 foo 가 TDZ에 의해 초기화되기 전에 액세스 할 때 발생되는 ReferenceError 에러가 발생합니다.
TDZ (Temporal Dead Zone)
- TDZ란 변수가 선언되고 초기화되기의 범위를 TDZ(Temporal Dead Zone)에 있다고 합니다.
- TDZ의 영향을 받는 구문으로는 다음과 같습니다.
1) const 변수
2) let 변수
3) class 구문
4) constructor() 내부의 super()
5. 기본 함수 매개변수 (default Function Parameter)
- TDZ의 영향을 받지 않는 구문으로는 다음과 같습니다.
1) var 변수
2) 함수 선언식
const
const 키워드는 상수를 선언하기 위해 사용합니다. 특징은 let과 대부분 동일합니다.
01. 선언과 초기화
const 키워드로 선언한 변수는 반드시 선언과 동시에 초기화해야 합니다.
const num = 10;
const x; //SyntaxError
let처럼 블록 레벨 스코프를 가지며, 변수 호이스팅이 발생하지 않는 것처럼 동작합니다.
//호이스팅이 발생하지 않는것처럼 보인다.
{
console.log(num); // ReferenceError
const num = 10;
console.log(num); // 10
}
// 블록 레벨 스코프 를 가진다.
console.log(num); // ReferenceError
02. 재할당 금지
const는 처음 선언과 초기화를 가지고 나면, 재할당이 불가능합니다.
const x = 5;
console.log(x); // 5
x = 10;
console.log(x); // TypeError
03. 상수
const 키워드로 선언한 변수에 원시값을 할당한 경우 변수 값을 변경할 수 없습니다.
*원시값(immutable value): 변경불가능한 값
상수는 프로그램 전체에서 공통적으로 사용하므로 상태 유지와 가독성, 유지보수의 편의를 위해 적극적으로 사용해야 합니다.
04. 대문자 사용
- 대문자 상수는 ‘하드 코딩한’ 값의 별칭을 만들 때 사용하면 됩니다.
- 기억하기 힘든 값을 변수에 할당해 별칭으로 사용하는 것은 널리 사용되는 관습입니다. 이러한 상수는 대문자와 밑줄로 구성합니다.
const COLOR_RED = "#F00";
const COLOR_GREEN = "#0F0";
const COLOR_BLUE = "#00F";
const COLOR_ORANGE = "#FF7F00";
// 색상을 고르고 싶을 때 별칭을 사용할 수 있게 되었습니다.
let color = COLOR_ORANGE;
alert(color); // #FF7F00
- 사용하는 이유
- 값보다 상수가 더 기억하기 쉬워야 한다
- 값보다 상수를 사용하는 것이 오타를 낼 확률이 낮다
- 값보다 상수가 훨씬 유의미함으로써 코드 가독성이 증가한다
'DEVELOPMENT > JavaScript' 카테고리의 다른 글
[JS] 나를 위한 배열과 Date 메서드 컨닝페이퍼 (1) | 2025.01.22 |
---|---|
[JS] 정규표현식 (RegExp) (0) | 2024.06.21 |
[JS] Todo-List (1) | 2024.05.13 |
[JS] 견종 정보 페이지 (3) | 2024.05.03 |
[JS] Random Number Game (0) | 2024.04.30 |