2013-12-21 2 views
2

바와 같이 다음 단계는 제어 함수 오브젝트 F, thisArg 제공된 호출자 에 포함되는 기능 코드의 실행 컨텍스트 및 argumentsList 제공된 호출자 진입 할 때 수행 sec 10.4.3변수/어휘 환경

했다 :

  1. 기능 코드가 strict 코드 인 경우 thisBinding을 thisArg로 설정하십시오.
  2. 그렇지 않으면 thisArg가 null이거나 정의되지 않은 경우 ThisBinding을 전역 객체로 설정하십시오.
  3. 그렇지 않으면 Type (thisArg)이 Object가 아닌 경우 ThisBinding을 ToObject (thisArg)로 설정하십시오.
  4. 다른 사람은 this 바인딩을 thisArg로 설정합니다.
  5. LocalEnv를 NewDeclarativeEnvironment를 호출 한 결과로 지정하고 F의 [Scope]] 내부 속성 값을 인수로 전달합니다.
  6. LexicalEnvironment를 localEnv로 설정하십시오.
  7. VariableEnvironment를 localEnv로 설정하십시오.
  8. 코드를 F의 [[코드]] 내부 속성 값으로 지정하십시오.
  9. 10.5에서 설명한대로 함수 코드 code 및 argumentsList를 사용하여 선언 바인딩 바인딩을 수행합니다. 우리의 기능

    1. 코드
    2. thisArg가 null 따라서, ThisBinding하는 엄격한 코드를 밤은 : 우리는 다음이 따라서

      function foo(){ 
          var a={p:'p'}; 
          o={c:'c'}; 
      } 
      

      :

는 다음 코드를 고려 전역 개체로 설정

  • ---
  • ---
  • 어떤 바인딩이 포함되는지 이해하지 못합니다. environment record[[Scope]]으로 표시됩니다.
  • 설정 단계 5.
  • 에 geted 환경으로 설정 LexicalEnvironment instatiation 바인딩 선언문 수행 단계 5.
  • 에 geted 환경에 VariableEnvironment.
  • 8 단계에서 바인딩은 VariableEnvironment에 만들어 지지만 LexicalEnvironment에는 만들어지지 않습니다. 그러나 sec 10.3에서 실행 컨텍스트가 LexicalEnvironment 및 VariableEnvironment 성분을 생성

    초기에 동일한 값을 가지고있다.

    질문 : 실행 컨텍스트 LexicalEnvironment 및 VariableEnvironment의 생성은 여전히 ​​위 내 경우에는 동일 직후 왜

    ?

    +0

    질문을 이해할 수 있을지 잘 모르겠습니다. 'LexicalEnvironment'와'VariableEnvironment'는 6과 7에 할당 된 동일한 값을 갖습니다. –

    +0

    @Felix Kling 컨텍스트 생성의 8 단계에서 코드에 선언 된 변수와 함수가 VariableEnvironment의 환경 레코드에서 바인딩으로 추가됩니다. 그러나 LexicalEnvironment는 어떻습니까? 이 바인딩이 8 단계에서 LexicalEnvironment에 추가됩니까? 그리고 특정 사례에서 기능의 내부 속성은 무엇입니까? –

    +0

    좋은 질문입니다. 나는 그것이 객체와 비슷하다고 가정 할 것이다 : LexicalEnvironment와 VariableEnvironment는 동일한 환경을 참조하므로, 그 환경에 대한 모든 변경은 두 컴포넌트를 통해 볼 수있다. 예제에서 전역 범위에서 함수를 정의했기 때문에'[[Scope]]'는 전역 실행 컨텍스트의 어휘 환경을 참조합니다. http://www.ecma-international.org/ecma-262/5.1/#sec-13 –

    답변

    2

    은 내가 당신의 질문을 이해 잘 모르겠지만, 이것은 내가 초 10.4.3 이해하는 방법이다 :이 값 다루고있는 1 4

    이 단계를. 기본적으로 엄격 모드에서 전역 개체 (브라우저의 경우 window)를 기본값으로 사용하는 대신 thisnull 또는 undefined 값으로 남습니다. 이것은 일반적인 객체 또는 이벤트 핸들러 메커니즘을 통해 함수가 호출되지 않는 경우를 다룹니다.

    5 단계에서까지를 입력하면 함수를 입력 할 때마다 새 명명 환경이 만들어집니다. 현재 환경 범위를 형성하기 위해 이전 환경에 링크 된이 환경의 작성을 설명합니다.

    각 새 기능에 대해 두 환경이 공존합니다. 이름이 해석되면 먼저 어휘 환경이 검색되고 변수 환경이 검색됩니다. 두 검색이 모두 실패하면 '포괄적 인'전체 범위가 발생할 때까지 프로세스가 환경 체인의 상위 수준에서 반복됩니다. 이 범위에서 모든 식별자는 전역 (window) 개체의 속성으로 처리됩니다. with (window) 블록으로 묶인 전체 코드로 그림을 그릴 수 있습니다.

    어휘 환경은 변수 범위의 일시적인 증가로 볼 수 있습니다. 어휘 및 변수 환경은 with 또는 catch이라는 두 개의 특정 명령문을 사용하여 어휘 환경을 변경할 때까지 어휘 환경을 (기능적으로는)으로 변경해야합니다. 그것은 그들이 동일한 데이터 구조로 구현된다는 것을 의미하지는 않습니다.

    구현 측면에서 어휘 환경을 빈 목록으로, 변수 환경을 모든 로컬 변수 및 매개 변수 이름을 포함하는 목록으로 상상할 수 있습니다. catch 또는 with 문을 발견하면 어휘 목록에 변수 목록에 저장된 단어보다 우선 순위가 높은 새로운 이름이 채워집니다.

    catch은 인수를 이름 확인에 사용하기 만하면됩니다 (예외 매개 변수를 참조 할 수 있음). 새 이름이 함수 매개 변수만큼 명확하기 때문에 큰 문제는 없습니다.

    with은 다소 위험한 동물입니다. 인수로 전달 된 객체의 모든 속성 이름을 사용하여 새 환경을 만듭니다. 범위는 변수 환경과이 새로운 어휘 환경의 체인으로 구성됩니다. 해상도에 사용할 수있는 새 이름이 개체 내부에 '숨겨져 있습니다.'예를 들어 : oa라는 이름의 속성을 포함하고 있기 때문에

    var a = 'a', b = 'surprise!', o = {a:'a'}; 
    with (o) { a = b; } 
    console.log (a+" "+b+" "+o.a); 
    

    a surprise! surprise! 
    

    a을 얻을 것은 o.a으로 해결됩니다. b이 어휘의 환경에 없으므로 현재 변수 환경이 시도되고 변수 'b'이 발견되었습니다. 이것은 꽤 위험한 메커니즘입니다. 왜냐하면 객체가 실제로는 그렇지 않지만 주어진 속성을 포함한다고 생각하면 대신 현재 범위 밖의 변수를 참조하기 때문입니다. 예를 들어 ,이 같은 간단한 오타 : 현재 범위에 어딘가에 leftt라는 변수를 선언 한 일이없는 한

    with (element.style) {leftt = '10px';} 
    

    '10px'window.leftt 속성을 설정합니다.

    이제 개체 속성에 'i'또는 'j'와 같은 어리석은 이름을 지정하면 개체의 속성을 설정하는 동안 범위 체인 어딘가에 무작위 루프 인덱스가 사라질 가능성이 있습니다.

    단계 8은 기능 범위가 설정되면 매개 변수 바인딩을 설명합니다. 기본적으로 매개 변수는 값으로 바인딩되며 변수 이름은 변수 환경에 추가됩니다.

    개의 분리 환경을 유지하는 요점은 호이 스팅기구 항상 범위로 변수 환경 체인을 사용한다는 것이다.

    아이디어는 변수 나 함수가 현재 스코프 블록의 맨 위에 선언 된 것처럼 행동해야한다는 것입니다. 예를 들어 with 블록 내에서 선언 된 함수가 노출 된 객체 속성을 사용하여 해당 이름을 확인해서는 안됩니다. with 문.

    ECMA 사양은 블록 내에서 함수 선언을 허용하지 않으므로 솔직히 말하면, 논점의 결과와 함께 대부분의 구현이 그렇지만 말도 안됩니다.

    function foo(){ 
        var a={p:'p'}; 
        o={c:'c'}; 
    } 
    

    당신의 함수가 with 또는 catch 문을 포함하지 않기 때문에 내부의 범위 체인 'foo는()가'두 개의 변수 환경의 단지 목록은 다음과 같습니다 :

    global (a bunch of DOM objects all seen as properties of 'window') 
        function foo (var a) 
    
    귀하의 예를 들어 지금

    당신은 foo는()를 호출하면

    • a은 foo의 지역 변수로 해결되며 p 값 (값 'p')을 가진 객체로 만들어집니다 (영구 변수에서 참조를 관리하지 않는 한 foo()를 종료하자마자 가비지 수집됩니다).

    • o 푸의 변수 환경에서 찾을 수 없습니다, 그래서이 '캐치 올'전역 범위에 의해 체포되고, 따라서 window 객체의 (새) 속성으로 해결. 값이 'c'window.o.c 속성이 만들어집니다.

    귀하의 질문에 다소 답이 있습니까?

    +0

    일반적으로 어휘와 변수 환경의 차이를 이해하는 데 유용한 유용한 답변입니다. :) –