[Javascript] 스코프
스코프
const와 let을 사용해서 함수 외부에서 사용된 변수를 함수 내부에서도 사용하게 되면 어떻게 될까?
블록 내부의 feedback 변수는 서로 다른 스코프를 가지고 있기 때문에 서로 다른 변수로 여겨진다
let name = 'Son';
function f1() {
let name = 'Kim';
f2();
}
function f2() {
console.log(name);
}
f1(); // ? => Son
다음 코드를 살펴보자.
let x = 10;
function foo() {
x = 100;
console.log(x);
}
foo(); // 100
console.log(x); // ? => 100
이와 같은 경우는 중복선언이 아니라 글로벌 영역에서 선언된 변수 x를,
함수 foo에서 변수에 값을 재할당 하는 것이므로 x값이 변경된다.
실행 컨텍스트 관점에서 설명해보자면,
위 코드에서는 총 1. 전체스크립트 렉시컬 environment 2. 함수 렉시컬 environment , 이렇게 두가지가 만들어진다.
foo() 함수를 실행하는 순간 함수 렉시컬 환경이 생성되는데
이 렉시컬 환경은 환경 레코드와 외부 렉시컬 환경으로 구성되어 있음.
환경 레코드에는 선언된 변수,함수, this 값 등이 저장되고,
외부렉시컬 environment에는 부모환경에 접근 할 수 있는 참조값을 가지고 있다.
함수가 선언된 시점 기준으로 그 외부 환경을 참조하므로 외부환경인 글로벌 렉시컬 env의 환경레코드에 있는 변수 x를 참조 할 수 있다.
⇒ 요약 : foo 함수내에서 글로벌 영역의 환경 레코드에 있는 변수 x를 참조할 수 있다. 변수값이 변경됨.
“렉시컬 스코프는 함수를 어디서 호출하는지가 아니라 어디에 선언하였는지에 따라 결정된다.”
이 말이 방금 설명한 내용 그대로다.
암묵적 전역
console.log(x); // undefined
console.log(y); // Reference Error
let x = 10;
function foo() {
y = 100;
console.log(x + y);
}
foo(); // ? => 110
y가 선언된 스코프를 함수 스코프와 글로벌 스코프에서도 찾을 수 없기 때문에
foo함수를 실행하면 참조에러가 발생해야 할 것 같으나,
자바스크립트 엔진은 y = 20을 window.y = 20으로 해석하여 프로퍼티를 동적 생성한다.
결국 y는 전역 객체의 프로퍼티가 되어 마치 전역 변수처럼 동작한다. 이러한 현상을 **암묵적 전역(implicit global)**이라 한다. 하지만 winodw객체의 프로퍼티일 뿐, 변수가 아니므로 호이스팅은 발생안함!