[JS] Scope

은채·2022년 6월 5일
0

JavaScript

목록 보기
12/26
post-thumbnail

Scope

  • 유효 범위
  • 변수의 접근성과 생존 기간을 제어

예제

func1()의 값이 왜 3일까?
전역에 a = 20을 해주었는데?

함수 안에 있는 a는 함수 안에서만 존재하고, 전역에 있는 a는 영향을 미치지 못한다.
=> 함수 선언 다음에 있어서 , 값을 할당했지만 함수 스코프안에 있는 a가 반영된다.
함수 밖에서 b의 값을 알아보고 싶어도? 알아볼 수 없다.
=> 함수 스코프 공간 안에 있기 때문에, 전역에서는 함수 스코프 안으로 접근 할 수 없다.

즉, 스코프는 이름 충돌 문제를 덜어주고, 자동으로 메모리를 관리한다
다른 공간에 있기 때문에, 변수의 이름이 같아도 원하는 결과를 얻을 수 있다.
함수 스코프 안에 있는 변수는 함수가 리턴되면 모두 해제됨

자바스크립트의 유효범위

1. 전역 스코프

: 스크립트의 어디서든 접근이 가능하기 때문에 사용이 쉽다. 하지만 타인과의 협업, 라이브러리 사용시 충돌의 가능성이 있다.

2. 함수 스코프

: 함수 내부에서 정의된 변수와 매개변수는 함수 외부에서 접근할 수 없다.
함수 내부에서 정의된 변수라면 함수의 어느 부분에서도 접근할 수 있다.

func1()가 실행되면서 12가 출력되었다.
func2()안에서는 a라는 변수를 선언한 적이 없다.
하지만 func2는 부모함수 안에서 선언된 함수이기 때문에 부모 함수 안을 탐색할 수가 있게 된다.
그렇게 변수 a를 사용할 수 있게 되었다.

전역 공간에서 어떻게 val을 읽어올 수 있었을까?
이는 var을 사용해서 선언한 것이 아니기 때문이다. (선언된 변수가 아니고 전역변수로 인식)

3. 블록 스코프 (es6)

: 중괄호 안에서만 접근이 가능하다.
블록 내부에 정의된 변수는 블록의 실행이 끝나면 해제된다.

let을 사용하게 되면 { } 블록 스코프 안에서만 존재하는 변수가 된다
전역공간에서 value를 접근한다면, var로 선언한 value가 읽힌다.


정의

스코프란 자바스크립트 엔진이 참조의 대상이 되는 식별자(Identifier)를 검색할 때 사용하는 규칙의 집합 
즉, 어떤 변수를 사용하거나 함수를 호출하려고 할 때 해당하는 식별자로 사용하는데, 그 식별자를 검색하는 메커니즘이라고 이해하면 된다.

현재 실행되는 컨텍스트
변수가 참조 될 수 있는 접근 가능한 유효 범위
식별자 (변수, 함수, 클래스 이름 등) 가 유효한 범위
만약 변수 또는 다른 표현식이 "해당 스코프"내에 있지 않다면 사용할 수 없음.
선언된 위치에 따라 유효 범위가 결정 된다

스코프는 계층적인 구조를 가지기 때문에 하위 스코프는 상위 스코프에 접근할 수 있지만 반대는 불가하다.
블럭 안의 변수는 블럭 안에서만 유효 - 이름 충돌 방지, 블럭이 끝나면 자동으로 메모리에서 삭제 (절약)
블럭 외부에서는 블럭 내부의 변수를 참조할 수 없다

블럭 : {} , if(){}, for(){}, function(){}

따라서 변수는 최대한 필요한 곳에서 지정해야 함!

렉시컬 스코프

변수 및 함수/블록 스코프를 어디에 작성하였는가에 따라 정해지는 스코프 를 렉시컬 스코프라고 한다. "렉시컬(Lexical)" 이라는 명칭이 붙은 이유는 자바스크립트 컴파일러가 소스코드를 토큰(Token)으로 쪼개서 의미를 부여하는 렉싱(Lexing) 단계에 해당 스코프가 확정되기 때문이다. 다시 쉽게 말하면, 변수 혹은 함수/블록이 어디에 써있는가를 보고 그 스코프를 판단하면 된다.

스코프 체인

현재 스코프에서 식별자를 검색할 때 상위 스코프를 연쇄적으로 찾아나가는 방식 을 말한다. 실행 컨텍스트를 배웠다면 생성될 때마다 LexicalEnvironment가 만들어지고 그 안에 outer 참조 값이 있다는 것을 알 것이다. 바로 이 outer 참조 값이 상위 스코프의 LexicalEnvironment를 가리키기 때문에 이를 통해 체인처럼 연결되는 것이다.

즉, 다음과 같은 과정으로 스코프 체인을 검색한다.

  1. 현재 실행 컨텍스트의 LexicalEnvironment의 EnvironmentRecord에서 식별자를 검색한다.
  2. 없으면 outer 참조 값으로 스코프 체인을 타고 올라가 상위 스코프의 EnvironmentRecord에서 식별자를 검색한다.
  3. 이를 outer 참조 값이 null 일 때까지 계속하고 찾지 못한다면 에러를 발생시킨다.
profile
반반무마니

0개의 댓글