[ydkjsy]Scope & Closures-1-What's the Scope?

p*0*q·2021년 1월 3일
0

YDKJS

목록 보기
5/16

Compiled vs. Interpreted

컴파일은 컴퓨터가 알아들을 수 있는 말로 바꾸는 과정으로 한번에 처리되는 것이 일반적이다. interpreted도 목적은 같으나 line by line으로 다음 줄로 넘어가기 전 실행을 하고 다른 형태를 취할 수 있으며 현대 JS 엔진은 프로그램 처리 시 컴파일과 해석의 다양한 변형을 허용. JS는 컴파일 언어다.

Compiling Code

스코프는 컴파일 과정에 결정된다. classic compiler theory의 3단계를 간단히.
var a = 2;
1. Tokenizing/Lexing: 의미있는 단위(토큰)으로 분해. whitespace는 항상 의미가 없지는 않다. var,a,=,2,;
토큰화는 쪼개는 것. 렉싱은 의미부여도 하는 것.
2. Parsing: 토큰 배열을 프로그램의 문법 구조를 나타내는 AST(Abstract Syntax Tree)를 만든다. VariableDeclaration의 child 두개.Identifier(value는 a), AssignmentExpression(child NumericLiteral(value는 2)).
3. Code Generation: AST를 갖고 실행가능한 코드를 만든다.

Required: Two Phases

JS 스펙에서는 컴파일을 명시적으로 요구하진 않지만 컴파일 후 실행 방식을 요구함. 증거로

  • Syntax Errors from the Start
  • Early Errors
  • Hoisting
    즉, 실행 전, 전체적으로 parsed.
    그리고 AST에서 컴파일하지 않고 프로그램 실행 가능하지만 비효율적.

Compiler Speak

컴파일 시 어떻게 JS엔진이 변수를 식별하고 스코프를 결정할까?
LHS(target) = RHS(source) 보통 이렇게 생각할텐데 꼭 이 형식을 유지하는 것이 아니기 때문에 변수의 경우, 값의 할당 유무로, 할당되면 target, 아니면 source로 생각하는 것이 좋다.

var students/*t*/ = [
    { id: 14, name: "Kyle" },
    { id: 73, name: "Suzy" },
    { id: 112, name: "Frank" },
    { id: 6, name: "Sarah" }
]/*s*/;

function getStudentName/*t*/(studentID/*t*/) {// 컴파일시 선언된 식별자. 함수와 식별자 연결을 자동으로 scope 시작할때 설정됨. = 실행되는것을 기다리지 않고.
    for (let student/*t*/ of students/*s*/) {
        if (student/*s*/.id == studentID/*s*/) {
            return student/*s*/.name;
        }
    }
}

var nextStudent/*t*/ = getStudentName/*s*/(73);

console/*s*/.log(nextStudent/*s*/);
// Suzy

이런 변수의 역할이 lookup(특히 실패시)을 살펴보는데 중요.

Cheating: Runtime Scope Modifications

계속 컴파일 시 스코프가 결정된다고 했는데, non-strict에서 런타임 동안에 수정 가능하지만 쓰지마.

function badIdea() {
    eval("var oops = 'Ugh!';");
    console.log(oops);
}
badIdea();   // Ugh! // 런타임 중에 실행중에 현재 범위 수정
// eval이 없었다면 ReferenceError

var badIdea = { oops: "Ugh!" };
// 객체를 로컬 스코프로 바꿈.
with (badIdea) {
    console.log(oops);   // Ugh!
}

Lexical Scope

컴파일 시에 스코프가 정해지는 것을 Lexical Scope라고 한다. var는 함수 스코프, let/const는 블록 스코프. 변수 참조, 현재 스코프를 찾고 없으면 바깥 스코프로..찾을 때까지 반복하고 없으면 에러.

컴파일은 실제로 메모리 예약 같은 것을 하지 않고, 프로그램에서 필요한 렉시컬 스코프 지도를 만든다. 즉, 스코프가 필요할 때마다 만드는 것이 아니고, 런타임에 사용할 지도를 컴파일시에 만든다.

0개의 댓글

관련 채용 정보