안녕하세요:) 웹 파트 YB 유서연입니다!
이번 글에서는 2주차 세미나 내용 중 흥미로웠던 '스코프'에 대해 알아보겠습니다.
스코프란?
function add(x,y) {
console.log(x, y); // 2 5
return x + y;
}
add(2, 5);
console.log(x, y); // ?
위 코드에서 함수 add 외부의 console.log(x, y);는 무엇을 출력할까요?
우리는 ReferenceError를 발생시킬 것이라 예상할 수 있습니다.
왜냐하면, x와 y 값은 함수를 호출할 때 지정하는 매개변수이므로 함수 내부에서만 참조할 수 있기 때문이죠.
이처럼 변수를 참조할 수 있는 유효 범위를 '스코프'라고 합니다.
자바스크립트 엔진은 스코프를 통해 어떤 변수를 참조해야 할 것인지 결정합니다.
따라서, 스코프는 "식별자를 검색하는 규칙"이라고도 할 수 있습니다.
✏️ 스코프 : 식별자를 참조할 수 있는 유효 범위, 식별자를 검색하는 규칙
💡 var 키워드로 선언한 변수의 중복 선언
function foo () {
var x = 1;
var x = 2;
console.log(x); // 2
}
foo();
var 키워드로 선언된 변수는 같은 스코프 내에서 중복 선언을 허용합니다.
이에 따라 의도치 않게 변수값을 재할당하는 문제가 발생할 수 있습니다.
이러한 문제를 해결하는 것이 let과 const 입니다.
let이나 const 키워드로 선언된 변수는 같은 스코프 내에서 중복 선언을 허용하지 않습니다.
스코프의 종류
자바스크립트에서 스코프는 크게 전역 스코프와 지역 스코프로 구분할 수 있습니다.
1. 전역 스코프 (Global Scope)
- 전역 : 코드의 가장 바깥 영역
- 전역 변수는 어디서든지 접근이 가능하여 코드 전역에서 참조할 수 있습니다.
2. 지역 스코프 (Local Scope)
- 지역 : 함수 몸체 내부
- 지역 변수는 선언된 함수 내부 또는 해당 지역 스코프와 그 하위 스코프에서만 유효합니다.
스코프 체인 (Scope Chain)
✏️ 스코프 체인 : 스코프가 함수의 중첩에 의해 하나의 계층적 구조로 연결된 것
변수를 참조할 때 자바스크립트 엔진은 스코프 체인을 통해 변수를 참조하는 코드의 스코프에서 시작하여 상위 스코프 방향으로 이동하며 선언된 변수를 검색합니다.
위 그림에서 inner 함수는 x 변수를 참조할 때 자신의 스코프에 존재하지 않으므로 상위 스코프 방향으로 이동하며 변수를 검색합니다.
함수 레벨 스코프 vs 블록 레벨 스코프
자바스크립트에서 var 키워드로 선언된 변수는 함수 레벨 스코프를 가집니다.
이는 코드 블록 {} 내에서 선언되더라도 블록 바깥에서 유효하다는 의미입니다.
반면, let과 const는 블록 레벨 스코프를 가지며, 선언된 코드 블록 내에서만 유효합니다.
- 함수 레벨 스코프 : var 키워드로 선언된 변수는 오로지 함수의 코드 블록(함수 몸체)만을 지역 스코프로 인정
var x = 1;
if (true) {
var x = 10;
}
console.log(x); // 10
위 코드에서 x는 코드 블록 내에서 재선언되었지만, var는 함수 레벨 스코프를 따르므로 x 변수가 전역에서 참조됩니다.
- 블록 레벨 스코프 : 대부분의 프로그래밍 언어는 모든 코드 블록({})을 지역 스코프로 인정
let y = 1;
if (true) {
let y = 10;
}
console.log(y); // 1
let을 사용한 위의 코드에서 y는 블록 스코프 내에서만 유효하므로 코드 블록 바깥의 y는 1 입니다.
렉시컬 스코프 (Lexical Scope)
상위 스코프를 결정하는 방식으로는 두 가지가 있습니다.
- 동적 스코프 : 함수를 어디서 호출했는지에 따라 함수의 상위 스코프 결정
- 함수가 호출되는 시점에 동적으로 상위 스코프를 결정합니다.
- 렉시컬 스코프 (정적 스코프) : 함수를 어디서 정의했는지에 따라 함수의 상위 스코프 결정
- 함수 정의가 평가되는 시점에 상위 스코프가 정적으로 결정됩니다.
자바스크립트는 "렉시컬 스코프"를 따릅니다.
이는 함수가 정의된 위치에 따라 상위 스코프가 결정되며, 호출 위치는 상위 스코프 결정에 영향을 주지 않는다는 의미입니다.
var x = 1;
function foo(){
var x = 10;
bar();
}
function bar(){
console.log(x);
}
foo(); // 1
bar(); // 1
위 코드에서 bar 함수는 foo 함수 내에서 호출되었지만, 상위 스코프는 함수가 정의된 위치에 따라 전역 스코프입니다.
따라서, 전역 변수 x의 값인 1이 두 번 출력됩니다.
'2주차' 카테고리의 다른 글
dialog 태그로 모달창 구현하기! (0) | 2024.10.29 |
---|---|
[JavaScript] 자바스크립트의 데이터 타입에 대해.araboza (0) | 2024.10.29 |
🤫 NaN을 조심하세요... (0) | 2024.10.29 |
[JS] 자바스크립트 가비지 컬렉션 (GC) (0) | 2024.10.29 |
[JS] localStorage 사용법을 알아보자. (0) | 2024.10.29 |