Frontend/Javascript

[Javascript] 스코프

baegopeunGom 2023. 8. 9. 21:40

스코프

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객체의 프로퍼티일 뿐, 변수가 아니므로 호이스팅은 발생안함!