study: javascript | 숨참고 deep dive (13) 스코프 - 221207

Lumpen·2022년 12월 6일
0

Study

목록 보기
16/92

1. 스코프

스코프 (유효범위)는 자바스크립트를 포함한 모든 프로그래밍 언어의 기본이며 중요한 개념이다
자바스크립트의 스코프는 다른 언어와 구별되는 특징이 있다
var, let, const 키워드로 선언한 변수는 각각 다르게 동작한다
스코프는 변수와 함수에 밀접한 관계가 있다
함수의 이름과 매개변수는 함수의 몸체에서만 참조할 수 있다 이런 것이 스코프다

변수는 코드의 가장 바깥 영역뿐 아니라 코드 블록이나 함수 몸체 내에서도 선언할 수 있다
이 때 코드 블록이나 함수는 중첩될 수 있다

모든 식별자는 자신이 선언된 위치에 의해 자신이 유효한 범위, 
즉 다른 코드가 자신을 참조할 수 있는 범위가 결정된다

이를 스코프라 하고 스코프란 식별자가 유효한 범위를 뜻한다

어떤 식별자를 참조하려 할 때 다른 스코프에 같은 이름의 식별자가 있다면
어떤 스코프의 식별자를 참조할지 결정하는 것을 식별자 결정이라고 한다
스코프란 자바스크립트 엔진이 식별자를 검색할 때 사용하는 규칙이라고 보면 된다

자바스크립트 엔진은 코드를 실행할 때 코드의 문맥을 고려한다
어디서 실행되고 주변에 어떤 코드가 있는지에 따라 동일한 코드도 다른 결과를 가져온다

코드의 문맥과 환경

코드가 어디서 실행되며 주변에 어떤 코드가 있는지를 렉시컬 환경이라고 부른다 (정적 환경)
코드의 문맥은 정의될 때 결정되는 렉시컬 환경으로 이루어진다
이를 구현한 것이 실행 컨텍스트이며 모든 코드는 실행 컨텍스트에서 평가되고 실행된다

식별자는 값을 구분할 수 있어야하므로 유일해야 한다
스코프 내에서 유일하면 된다

2. 스코프의 종류

코드는 전역과 지역으로 구분할 수 있다

코드의 가장 바깥 영역에 작성하면 전역 스코프, 전역 변수
함수 몸체 내부에 작성하면 지역 스코프, 지역 변수

전역 변수는 어디서든 참조할 수 있다
지역 변수는 자신의 지역 스코프와 하위 지역 스코프에서 유효하다
자바스크립트 엔진은 스코프 체인을 통해 참조할 변수를 검색한다

스코프 체인

함수는 전역에서 정의할 수도 있고 함수 몸체 내부에서 정의할 수도 있다
함수의 몸체 내부에서 정의하는 것을 함수의 중첩이라고 한다

다른 함수의 몸체 내부에서 정의된 함수를 중첩 합수라고 하고
중첩 함수를 포함하는 함수를 외부 함수라고 한다

함수는 각자의 스코프를 갖기 때문에
함수가 중첩된다는 것은 스코프도 중첩이 된다는 것이다
스코프는 함수의 중첩에 의해 계층적 구조를 갖는다
이 때 외부 함수의 스코프를 중첩 함수의 상위 스코프라고 한다

모든 스코프는 하나의 계층적 구조로 연결되며
모든 지역 스코프의 최상위 스코프는 전역 스코프다
스코프가 계층적으로 연결된 것을 스코프 체인이라고 한다

변수 참조 시 자바스크립트 엔진은 스코프 체인을 통해 
변수 참조 코드의 스코프에서 시작하여 상위 스코프 방향으로 이동하며
변수를 검색한다

변수 참조는 자바스크립트 엔진에서 일어난다는 부분..

스코프 체인은 물리적인 실체로 존재한다
자바스크립트 엔진은 코드를 실행하기 이전에
자료구조로 렉시컬 환결을 생성한다
변수 선언이 되면 변수 식별자가 렉시컬 환경 자료구조에 키로 등록되고
변수 할당이 일어나면 변수 식별자에 해당하는 값을 변경한다
검색 또한 이 자료구조에서 일어난다

렉시컬 환경

스코프 체인은 실행 컨텍스트의 렉시컬 환경을 단방향으로 연결한 것이다
전역 렉시컬 환경은 코드가 로드 되면 곧바로 생성되고
함수의 렉시컬 환경은 함수가 호출되면 곧바로 생성된다

스코프 체인에 의한 변수 검색

변수 참조는 변수를 참조하는 코드가 있는
해당 스코프에서 변수를 검색한다
해당 스코프에 참조하려는 변수가 없을 경우
스코프 체인의 상위 스코프에서 변수를 검색한다
전역 스코프 까지 탐색을 마친 후에도 참조를 할 수 없다면
참조 에러를 발생시킨다

상위 스코프에서 유효한 변수는 하위 스코프에서 참조할 수 있지만
하위 스코프의 변수는 상위 스코프에서 참조할 수 없다
스코프 체인의 계층적 구조는 상속과 유사하다

스코프 체인에 의한 함수 검색

함수 선언문으로 함수를 정의하면 런타임 이전에 함수 객체가 먼저 생성된다
자바스크립트 엔진은 함수 이름과 동일한 이름의 식별자를 암묵적으로 선언하고
생성된 함수 객체를 할당한다

모든 함수는 함수 이름과 동일한 이름의 식별자에 할당된다
함수도 식별자에 할당되기 때문에 스코프를 갖는다
이는 일반 변수와 다를 것이 없다
스코프는 식별자를 검색하는 규칙 이라고 생각하는 편이 좋다

함수 레벨 스코프

var 로 선언된 변수는 함수 레벨 스코프를 갖는다
코드 블록이 아닌 함수 블록만을 지역 스코프로 인정하는 것이다
함수 내부가 아닌 블록 내에서 선언된 var 변수는 모두 전역 변수다
때문에 의도치 않은 결과를 초래할 수 있다 - 재선언/재할당 도 모두 가능하기 때문

ES6 문법인 let 과 const 는 블록 레벨 스코프를 지원한다

렉시컬 스코프

함수를 어디에 정의했느냐에 따라 스코프가 결정되는 정적 스코프를 말한다
자바스크립트는 렉시컬 스코프를 따르기 때문에 함수를 어디서 호출했는지가 아닌
함수를 어디에 정의했는지에 따라 스코프가 결정된다
함수 정의가 실행되어 생성된 함수 객체는 스코프 체인에 의해 상위 스코프를 기억한다
함수 호출 시 상위 스코프를 참조할 필요가 있기 때문이다
렉시컬 스코프는 클로저와 관계가 있다

profile
떠돌이 생활을 하는. 실업자는 아니지만, 부랑 생활을 하는

0개의 댓글