문제

오늘 저는 JavaScript의 중첩 기능에 대해 동료와 토론했습니다.

function a() {
   function b() {
      alert('boo')
   }
   var c = 'Bound to local call object.'
   d = 'Bound to global object.'
}

이 예에서, 시험은 B가 C와 매우 유사한 A의 본체 밖에서 B에 도달 할 수 없음을 지적합니다. 그러나 D는 -()을 실행 한 후입니다. 이 동작의 정확한 정의를 찾고 ECMAScript v.3 표준 , 나는 내가 찾고 있던 정확한 문구를 찾지 못했습니다. Sec.13 P.71은 말하지 않는 것은 함수 선언문에 의해 생성 된 기능 객체가 바인딩 될 객체입니다. 내가 뭔가를 놓치고 있습니까?

도움이 되었습니까?

해결책

이것은 정적 범위입니다. 함수 내의 명령문은 해당 함수 내에서 스코핑됩니다.

그러나 JavaScript는 기발한 행동을 가지고 있습니다. var 키워드, 당신은 암시했다 글로벌 변수. 그것이 당신이 시험에서보고있는 것입니다. "D"변수는 함수 본문 내에 쓰여져 있음에도 불구하고 묵시적 글로벌이기 때문에 사용할 수 있습니다.

또한 질문의 두 번째 부분에 답하기 위해 : 함수는 변수와 마찬가지로 선언 된 범위에 어떤 범위가 존재합니다.

사이드 노트 : 당신은 아마도 글로벌 변수, 특히 암시되지 않은 변수를 원하지 않을 것입니다. 혼란을 방지하고 모든 것을 깨끗하게 유지하기 위해 항상 VAR 키워드를 사용하는 것이 좋습니다.

사이드 노트 :ECMA 표준은 아마도 JavaScript에 대한 답변을 찾는 데 가장 유용한 장소는 아니지만 확실히 나쁜 자원은 아닙니다. 브라우저의 JavaScript는 해당 표준의 구현 일 뿐이므로 표준 문서는 JavaScript 엔진을 구축 할 때 (주로) 이행과 함께 (대부분) 규칙을 제공 할 것입니다. 관심있는 구현, 즉 주요 브라우저에 대한 특정 정보를 제공 할 수 없습니다. 특히 주요 브라우저의 JavaScript 구현이 어떻게 작동하는지에 대한 직접적인 정보를 제공하는 몇 권의 책이 있습니다. 차이점을 설명하기 위해 ECMAScript 사양과 JavaScript의 책에서 아래의 발췌문을 포함하겠습니다. 이 책이보다 직접적인 답변을 제공한다는 데 동의 할 것입니다.

여기에 있습니다 ecmascript 언어 사양:

10.2 실행 컨텍스트를 입력합니다

함수가 재귀 적으로 호출되는 경우에도 모든 함수 및 생성자 호출은 새로운 실행 컨텍스트에 들어갑니다. 모든 반환은 실행 컨텍스트를 종료합니다. 잡힌 예외는 잡히지 않으면 하나 이상의 실행 컨텍스트를 종료 할 수 있습니다.

제어가 실행 컨텍스트에 들어가면 스코프 체인이 생성되고 초기화되며 가변 인스턴스화가 수행 되며이 값은 결정됩니다.

스코프 체인의 초기화, 가변 인스턴스화 및이 값의 결정은 입력되는 코드 유형에 따라 다릅니다.

여기에서 왔어요 오라일리의 JavaScript : The Definitive Guide (5 판):

8.8.1 어휘 스코핑

JavaScript의 함수는 동적으로 스코핑되는 대신 어휘입니다. 이것은 그들이 실행되는 범위가 아니라 정의 된 범위에서 실행한다는 것을 의미합니다. 함수가 정의되면 현재 스코프 체인이 저장되고 함수의 내부 상태의 일부가됩니다. ...

이러한 종류의 질문을 다루는 데 적극 권장되는 것은 Douglas Crockford의 책입니다.

JavaScript, 좋은 부품 http://oreilly.com/catalog/covers/9780596517748_cat.gif

자바 스크립트, 좋은 부분, O'Reilly에서도.

다른 팁

내가 이해 한 바와 같이, 범위에 관한 한, 이것들은 다음과 같습니다.

function a() { ... }

그리고

var a = function() { ... }

d가 "글로벌"으로 만들어지는 동안 실제로는 창 객체의 속성으로 만들어지고 있음을 주목하는 것이 중요합니다. 이것은 당신이 당신이 이미 창 객체에 이미 존재하는 것을 부주의하게 덮어 쓸 수 있음을 의미합니다. 그렇지 않으면 변수가 실제로 생성되지 않을 수 있습니다. 그래서:

function a() {
    d = 'Hello World';
}
alert(window.d); // shows 'Hello World'

그러나 당신은 할 수 없습니다 :

function a() {
    document = 'something';
}

Window.document 객체를 덮어 쓸 수 없기 때문입니다.

모든 실용적인 목적을 위해 모든 코드가 거대로 실행되고 있음을 이미징 할 수 있습니다. with(window) 차단하다.

JavaScript에는 두 개의 스코프가 있습니다. 글로벌 및 기능. "var"키워드를 사용하여 함수 내부에서 변수를 선언하면 해당 함수 및 내부 기능에 국한됩니다. 함수 이외의 변수를 선언하면 글로벌 범위가 있습니다.

드디어, 변수를 처음 선언 할 때 VAR 키워드를 생략하면 JavaScript가 글로벌 변수를 원한다고 가정합니다..

따라서 기능 A를 호출하고 기능 A는 전역 변수 d를 선언합니다. d.

...

function a() {
   function b() {
      alert('boo')
   }
   var c = 'Bound to local call object.'
   d = 'Bound to global object.'
}

앞서 나오지 않고 var, D는 글로벌입니다. D 비공개로 만들기 위해 다음을 수행하십시오.

function a() {
   function b() {
      alert('boo')
   }
   var c = 'Bound to local call object.'
   var d = 'Bound to local object.'
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top