제2 장 어법 작용 역

2.1 문법 단계
function foo(a) {
  var b = a * 2;
  function bar(c) {
    console.log( a, b, c );
  } 
  bar( b * 3 );
} 
foo( 2 ); // 2, 4, 12
  • 전체 전역 역할 영역 을 포함 하 는데 그 중에서 하나의 식별 자 만 있 습 니 다: foo.
  • foo 가 만 든 역할 도 메 인 을 포함 하 는데 그 중에서 세 개의 식별 자: a, bar 와 b 가 있다.
  • bar 가 만 든 역할 도 메 인 을 포함 하 는데 그 중에서 하나의 식별 자 만 있 습 니 다: c.

  • 어떠한 함수 도 없 는 기포 가 두 외부 작용 역 의 기포 에 동시에 나타 날 수 있다. 마치 어떤 함수 도 두 부모 급 함수 에 동시에 나타 날 수 없 는 것 과 같다.
    찾다
    역할 영역 찾기 는 첫 번 째 일치 하 는 식별 자 를 찾 을 때 중단 합 니 다.
    전역 변 수 는 자동 으로 전역 대상 (예 를 들 어 브 라 우 저의 window 대상) 의 속성 이 되 므 로 전역 대상 의 품사 이름 을 직접 사용 하지 않 고 전역 대상 속성 에 대한 인용 을 통 해 간접 적 으로 접근 할 수 있 습 니 다.
    window.a
    

    이 기술 을 통 해 동명 변수 에 가 려 진 전역 변 수 를 방문 할 수 있 습 니 다.그러나 전역 이 아 닌 변수 가 가 려 지면 어떻게 든 접근 할 수 없습니다.
    사기
    사기 어법 작용 역 은 성능 을 떨 어 뜨 릴 수 있다.
    2.2.1 eval
    function foo(str, a) {
      eval( str ); //   !
      console.log( a, b );
    }
    var b = 2;
    foo( "var b = 3;", 1 ); // 1, 3
    

    엄격 한 모드 의 프로그램 에서 eval (..) 이 실 행 될 때 자신의 품사 역할 영역 이 있 음 은 그 중의 성명 이 있 는 역할 영역 을 수정 할 수 없다 는 것 을 의미한다.
    자 바스 크 립 트 에는 eval (..) 과 비슷 한 기능 도 있다.setTimeout (..) 과 setInterval (..) 의 첫 번 째 매개 변 수 는 문자열 일 수 있 습 니 다. 문자열 의 내용 은 동적 으로 생 성 된 함수 코드 로 해석 할 수 있 습 니 다.이런 기능 들 은 이미 시대 에 뒤떨어 졌 고 결코 제창 되 지 않 는 다.사용 하지 마!
    new Function (..) 함수 의 행동 도 비슷 합 니 다. 마지막 매개 변 수 는 코드 문자열 을 받 아들 이 고 동적 으로 생 성 된 함수 로 바 꿀 수 있 습 니 다.이러한 구축 함수 의 문법 은 eval (..) 보다 약간 안전 하지만 되도록 사용 을 피해 야 한다.
    2.2.2 with
    with 는 보통 같은 대상 의 여러 속성 을 반복 적 으로 인용 하 는 단축 키 로 사용 되 며, 대상 자 체 를 반복 하지 않 아 도 됩 니 다.
    var obj = {
      a: 1,
      b: 2,
      c: 3
    };
    //         "obj"
    obj.a = 2;
    obj.b = 3;
    obj.c = 4;
    //        
    with (obj) {
      a = 3;
      b = 4;
      c = 5;
    }
    

    그러나 이 는 단순히 대상 속성 에 편리 하 게 접근 하기 위 한 것 이 아니다.다음 코드 를 고려 합 니 다:
    function foo(obj) {
      with (obj) {
        a = 2;
      }
    }
    var o1 = {
      a: 3
    };
    var o2 = {
      b: 3
    };
    foo( o1 );
    console.log( o1.a ); // 2
    foo( o2 );
    console.log( o2.a ); // undefined
    console.log( a ); // 2——  , a            !
    

    with 는 하나 도 없 거나 여러 개의 속성 이 있 는 대상 을 완전히 격 리 된 품사 역할 영역 으로 처리 할 수 있 기 때문에 이 대상 의 속성 도 이 역할 영역 에 정 의 된 품사 식별 자로 처 리 됩 니 다.
    with 블록 은 하나의 대상 을 품사 역할 영역 으로 처리 할 수 있 지만 이 블록 내부 의 정상 적 인 var 성명 은 이 블록 의 역할 영역 에 제한 되 지 않 고 with 가 처 한 함수 역할 영역 에 추 가 됩 니 다.
    o 2 의 역할 영역, foo (..) 의 역할 영역 과 전체 역할 영역 에서 식별 자 a 를 찾 지 못 했 기 때문에 a = 2 가 실 행 될 때 자동 으로 전체 변 수 를 만 들 었 습 니 다 (비 엄격 모드 이기 때 문).
    또 하 나 는 eval (..) 과 with 를 추천 하지 않 는 이 유 는 엄격 한 모델 에 영향 을 받 기 때문이다 (제한).with 는 완전히 금지 되 어 있 으 며, 핵심 기능 을 유지 하 는 전제 에서 간접 적 이거 나 비 안전 하 게 eval (..) 을 사용 하 는 것 도 금지 되 어 있다.
    2.2.3 성능
    JavaScript 엔진 은 컴 파일 단계 에서 여러 항목 의 성능 을 최적화 합 니 다.그 중에서 일부 최 적 화 는 코드 의 품사 에 따라 정태 적 인 분석 을 하고 모든 변수 와 함수 의 정의 위 치 를 미리 확인 해 야 실행 과정 에서 식별 자 를 신속하게 찾 을 수 있다.
    그러나 엔진 이 코드 에서 eval (..) 또는 with 를 발견 하면 식별 자 위치 에 대한 판단 이 모두 무효 라 고 간단하게 가정 할 수 있 습 니 다. 문법 분석 단계 에서 eval (..) 이 어떤 코드 를 받 을 지 명확 하 게 알 수 없 기 때 문 입 니 다. 이 코드 들 이 어떻게 역할 영역 을 수정 할 지,with 가 신조어 법 역할 도 메 인 을 만 드 는 대상 에 게 전달 하 는 내용 이 무엇 인지 알 수 없다.
    2.3 소결
    어법 작용 역 은 작용 역 이 코드 를 쓸 때 함수 성명 의 위치 에 의 해 결정 된다 는 것 을 의미한다.컴 파일 된 품사 분석 단 계 는 기본적으로 모든 식별 자가 어디 에 있 는 지, 어떻게 성명 하 는 지 알 수 있 고 실행 과정 에서 어떻게 찾 는 지 예측 할 수 있다.

    좋은 웹페이지 즐겨찾기