JavaScript
[모던 자바스크립트] 스코프
jjin502
2022. 7. 5. 19:41
스코프란 ?
- 스코프 : 유효 범위
// 13-1
function add(x, y) {
// 매개 변수는 함수 몸체 내부에서만 참조할 수 있다.
// 즉, 매개변수의 스코는 함수 몸체 내부.
console.log(x, y);
return x + y;
}
add(2, 5);
// 매개변수는 함수 몸체 내부에서만 참조할 수 있다.
console.log(x, y);
// Uncaught ReferenceError: x is not defined
// 13-2
// 스코프 : 모든 식별자(변수, 함수, 클래스 이름 등) 자신이 선언된 위치에 의해 다른 코드가 식별자 자신을 참소할 수 있는 유효 범위
// -> 식별자가 유효한 범위
var v1 = 1;
if (true) {
var v2 = 2;
if (true) {
var v3 = 3;
}
}
function foo() {
var v4 = 4;
function bar() {
var v5 = 5;
}
}
console.log(v1);
console.log(v2);
console.log(v3);
console.log(v4); // Uncaught ReferenceError: v4 is not defined
console.log(v5); // Uncaught ReferenceError: v5 is not defined
// 13-3
// 식별자 결정 : 자바스크립트 엔진은 이름이 같은 두 변수 중 어떤걸 참조할 것인지 결정함.
// 식별자를 검색할 때 사용하는 규칙
var v1 = "global"; // 어디든 참조 가능
function foo() {
var v1 = "local"; // foo 함수 내에서만 참조 가능
console.log(v1);
}
foo();
console.log(v1);
// local
// global
- 26,27번 라인 바뀌면 결과 값도 바뀌어서 나옴
- v1은 식별자 이름이 동일하지만, 스코프가 다른 별개의 변수
- 랙시컬환경 : 코드가 어디에서 실행되며 주변에 어떤코드가 있는지 코드의 문맥으로 이루어져 있음
- 이를 구현한 것 -> 실행 컨텍스트
var 키워드로 선언한 변수의 중복 선언
// 13-4
// 스코프 === 네임스페이스
// 네임스페이스 : 프로그래밍 언어에서 특정한 객체(Object)를 이름(Name)에 따라 구분할 수 있는 범위를 의미한다.
function foo() {
// var 키워드로 선언한 변수는 중복 선언이 가능하다.
var v1 = 1;
// 아래 변수 선언은 자바스크립트 엔진에 의해 var키워드가 없는 것처럼 동작한다.
var v1 = 2;
console.log(v1);
}
foo();
// 13-5
// let,const 키워드로 선언된 변수는 같은 스코프 내에서 중복선언을 허용하지 않는다.
function foo() {
// let or const 키워드로 선언한 변수는 중복 선언이 불가능하다.
let v1 = 1;
let v1 = 2;
console.log(v1);
// Uncaught SyntaxError: Identifier 'v1' has already been declared
}
foo();
스코프의 종류
- 전역 : 코드의 가장 바깥영역 → 어디든지 참조 가능하다.
- 지역 : 함수 몸체 내부 → 자신의 지역 스코프와 하위 지역스코프에서만 유효함
전역 스코프, 지역 스코프
- 함수가 중첩이 가능하므로 지역스코프도 중첩될 수 있다.
- 스코프가 함수 중첩에 의해 계층적 구조를 가진다.
- 이때 외부 함수의 지역 스코프를 중첩함수의 상위 스코프라 한다
스코프 체인
- 스코프 체인 : 스코프가 계층적으로 연결된것.
- 변수를 참조할 때 자바스크립트 엔진은 스코프 체인을 통해 변수를 참조하는 코드의 스코프에서 시작해 상위 스코프 방향으로 이동하여 선언된 변수를 검색함.
- 물리적으로 존재한다.
- 상위 스코프에서 유효한 변수는 하위 스코프에서 자유롭게 참조할 수 있지만, 하위 스코프에서 유효한 변수를 상위 스코프에서 참조할 수 없음
- 상속과 유사
스코프 체인에 의한 함수 검색
// 13-6
function foo() {
console.log("g fnc foo");
}
function bar() {
//
function foo() {
console.log("l fnc foo");
}
foo();
}
bar();
// l fnc foo
// 함수조 식별자에 할당되기 때문에 스코프를 가짐
// 따라서 스코프를 식별자를 검색하는 규칙이라고 표현하는게 적함
함수 레벨 스코프
- 함수 몸체 내부에서 생성된 스코프 === 지역 스코프
- 함수 레벨 스코프 : var키워드로 선언된 변수는 오로지 함수의 코드 블록만을 지역스코프로 인정함.
// 13-7
// 함수 레벨 스코프
var x = 1;
if (true) {
// var 키워드로 선언된 변수는 함수의 코드블록만을 지역스코프로 인정
// 함수 밖에서 var 키워드로 선언된 변수는 코드 블록 내에서 선언되었다할지라도 모두 전역변수임
// 따라서 x는 전역변수. 이미 선언된 전역변수 x가 있으므로 x변수는 중복 선언됨.
// 이는 의도치 않게 변수 값이 변경되는 부작용을 발생시킨다.
var x = 10;
}
console.log(x);
// 13-8
// for문에서 선언한 i는 전역 변수. 이미 선언된 전역변수 i가 있으므로 중복선언.
var i = 10;
for (var i = 0; i < 5; i++) {
console.log(i); // 0 1 2 3 4
}
// 의도치 않게 변수의 값이 변경
console.log(i); // 5
렉시컬 스코프
// 13-9
// 렉시컬 스코프
var x = 10;
function foo() {
var x = 10;
bar();
}
function bar() {
console.log(x);
}
foo();
bar();
// bar함수의 상위 스코프가 무엇인지에 따라 결정
// 1. 함수를 어디서 호출 -> 동적 스코프
// 2. 함수를 어디서 정의 -> 정적 스코프