2oneweek.dev

04. Lexical Environment

    Tags

  • JavaScript
04. Lexical Environment thumbnail

Lexical Environment(정적 환경)

var point = 123; function book() { function getPoint() {} } book();
  • 엔진이 쭉 문자열로 된 코드를 읽다가, 2번 째 줄의 function 키워드를 만나면 function object를 생성하고, 현재 스코프를 function object의 [[Scope]]에 설정한다. 함수 내부는 알 수 없다. 아직 함수 외부에서 코드를 읽고 있기 때문이다. 이 시점(엔진이 function 키워드를 만났을 때)에서 함수의 외부(Lexical Environment) 스코프가 결정된다.

    • es3에서는 호출시에 scope chain을 동적을 바꿔갔지만, es5에서는 엔진이 해석하는 단계에서 함수의 환경을 결정했다.(정적이다.)

  • 함수가 호출되면(5번 째 줄), function object의 [[Scope]]에 저장된 것을 execution context의 lexical environment component(LEC) -> 외부 렉시컬 환경 참조에 설정한다.

    • 여기서 실행 컨텍스트는 함수 호출 시에 생성됨을 알 수 있다.
    • LEC 내부에는 선언적 환경 레코드도 존재하는데, 여기는 함수 내부에 선언된 변수나 함수가 K/V로 들어간다.
  • 하나의 context에 들어갈 수 있도록 코딩을 하면, 메모리에 들락날락 거릴 필요 없어져, 엔진이 빠르게 동작할 수 있게된다.



But, Lexical Env에서 var 키워드 문제

  • 함수에서 var 키워드를 사용하지 않고 변수를 선언하면(a = 10), 글로벌 오브젝트에 설정된다. 현재 생성되는 컨텍스트가 글로벌 오브젝트로부터 X 단계 상위에 위치한다면, 타고 타고 올라가서 글로벌 오브젝트에서 식별자를 찾아와야한다.

  • 그러나, Lexical Environment는 function 키워드를 만났을 때, 그 외부 Scope 저장해 놓으므로, 글로벌 오브젝트에 설정된 변수를 참조할 수가 없다. (정적 환경에서는 함수 내부와 바로 외부, 두 개의 범위만 알고 있을 수 있다.)


해결책

  1. ES5에서는 "use strict"를 사용하면서 해결했다.

    • use strick 모드에선, 변수 선언 시 var 키워드를 빼면 에러가 난다. 근본적인 해결은 아닌듯
  2. ES6에서는 letconst 변수

    • 변수 자체에 Scope 제약을 둬서 lexical env를 유지하려고 한 것이다.

동적 환경

자바스크립트에는 동적 환경도 존재한다. 지금까지는 function 키워드를 만나면, 그때 Scope가 결정되었지만, 함수 실행 될 때마다 Scope가 만들어지게 만들 수 있다.

  1. with 문

    • JS 엔진은 with 문을 만나면 Scope를 생성한다. 반복문으로 with를 이뤄지면 루프만큼 scope를 생성하게 된다.
    • 그러나 with문은 strict 모드에선 에러가 발생한다. 따라서 use strict 사용으로 with문 사용을 배제할 수 있다.
  2. eval() 함수

    • 문자열에 감싸진 코드를 인자로 사용하기 때문에 막는 방법이 없다.
    • 그러나 보안에 문제가 있으므로 최대한 사용하지 말자. (어떤 문제가 있는지 알아보자.)
Written by@2-one-week
현재 블로그 개발 중

GitHubLinkedIn