이전 소개에서 우리는 javaScript에 블록 레벨 함수가없고 함수 수준 범위 만 있다는 것을 이미 알고 있습니다.
코드 사본은 다음과 같습니다.
함수 test () {// 범위
for (var i = 0; i <10; i ++) {// 범위가 아님
// 세다
}
Console.log (i); // 10
}
JavaScript에는 네임 스페이스가 표시되지 않으므로 모든 것이 글로벌 범위에 정의되어 있음을 의미합니다. 변수가 참조 될 때마다 JavaScript는 발견 될 때까지 전체 글로벌 범위를 통과합니다. 전체 글로벌 범위를 통해 변수가 여전히 찾을 수없는 경우 참조 오류 오류가 발생합니다.
그림 설명을 입력하십시오
암시 적 글로벌 변수
코드 사본은 다음과 같습니다.
// 스크립트 a
foo = '42';
// 스크립트 b
var foo = '42'
위의 두 가지 예제는 다른 효과가 있습니다. 첫 번째는 전역 범위에서 변수 foo를 정의하고 두 번째는 현재 범위에서 변수 foo를 정의합니다.
키워드 Var를 사용하지 않으면 예기치 않은 영향을 미칩니다.
코드 사본은 다음과 같습니다.
// 글로벌 범위
var foo = 42;
기능 test () {
// 로컬 범위
foo = 21;
}
시험();
foo; // 21
VAR은 함수 테스트에서 변수 FOO를 정의하는 데 사용되지 않으므로 함수 외부의 글로벌 변수 FOO가 덮어 씁니다. 큰 문제처럼 보이지는 않지만 수천 줄의 코드가 있다면 추적하기가 어려울 것입니다.
코드 사본은 다음과 같습니다.
// 글로벌 범위
var 항목 = [/ * 일부 목록 */];
for (var i = 0; i <10; i ++) {
Subloop ();
}
함수 subloop () {
// Subloop의 범위
for (i = 0; i <10; i ++) {// var 문 누락
// 놀라운 일을하십시오!
}
}
위의 예에서, 첫 번째 실행이 실행되면 외부 루프가 중지됩니다. Subloop 함수 내의 변수가 외부 글로벌 변수 i를 무시하기 때문입니다. 이 오류를 피하기 위해 함수 내부에 VAR을 추가하면되므로 변수를 정의 할 때 키워드 VAR을 추가하는 것을 잊지 않아도됩니다. 외부 글로벌 변수에 영향을 미치기를 원하지 않는 한.
로컬 변수
JavaScript의 로컬 변수는 두 가지 방식으로 만 생성 될 수 있으며, 하나는 키워드 Var를 통해 선언되며 다른 하나는 기능의 공식 매개 변수로 사용됩니다.
코드 사본은 다음과 같습니다.
// 글로벌 범위
var foo = 1;
var bar = 2;
var i = 2;
기능 테스트 (i) {
// 함수 테스트의 로컬 범위
i = 5;
var foo = 3;
바 = 4;
}
시험 (10);
현재 함수 테스트 내부의 변수 I 및 FOO는 로컬 변수이며 막대는 외부 글로벌 변수 막대를 무시합니다.
출입
JavaScript는 변수 선언을 홍보 할 것이므로 VAR 표현식 및 기능 선언이 모두 맨 위로 홍보됩니다.
코드 사본은 다음과 같습니다.
술집();
var bar = function () {};
var somevalue = 42;
시험();
기능 테스트 (데이터) {
if (false) {
goo = 1;
} 또 다른 {
var goo = 2;
}
for (var i = 0; i <100; i ++) {
var e = 데이터 [i];
}
}
위의 코드가 실행되기 전에 VAR 표현식 및 기능 테스트 선언이 상단으로 홍보되므로 프로그램은 정상적으로 실행되며 오류를보고하지 않습니다.
코드 사본은 다음과 같습니다.
// VAR 문이 여기에서 옮겨졌습니다
var bar, somevalue; // 기본적으로 '정의되지 않은'
// 함수 선언도 증가했습니다
기능 테스트 (데이터) {
var goo, i, e; // 누락 된 블록 범위가 여기에서 움직입니다
if (false) {
goo = 1;
} 또 다른 {
goo = 2;
}
for (i = 0; i <100; i ++) {
e = 데이터 [i];
}
}
술집(); // Bar는 여전히 '정의되지 않은'이므로 TypeError와 함께 실패합니다.
일부 값 = 42; // 과제는 들어오는 데 영향을받지 않습니다
bar = function () {};
시험();
JavaScript에는 블록 레벨 범위가 없으므로 VAR 표현식을 향상시킬뿐만 아니라 IF 구조를 덜 직관적으로 만듭니다.
위의 예에서는 글로벌 변수 goo에서 작동하는 경우 실제로 변수 goo가 홍보되므로 로컬 변수가 수정됩니다.
고도 규칙을 이해하지 못하는 경우 다음 코드에 참조 오류 오류가 발생한다고 생각할 수 있습니다.
코드 사본은 다음과 같습니다.
// 약간의 임시 모든 것이 초기화되었는지 확인하십시오
if (! somemportantthing) {
var somemportantthing = {};
}
물론, Code가 실행되기 전에 VAR 표현식이 상단으로 홍보 되었기 때문에 위의 코드는 잘못되지 않습니다.
코드 사본은 다음과 같습니다.
var importantthe;
// 다른 코드는 여기에서 몇 가지 중요한 것을 초기화 할 수 있습니다
// 거기에 있는지 확인하십시오
if (! somemportantthing) {
somemportantthing = {};
}
여기서는 @nightire fan ge의 블로그 게시물 "이해 JavaScript (ii)"를 추천하고 싶습니다.
이름 해상도 순서
함수 범위 내에서 Foo 변수에 액세스하려고 할 때 JavaScript는 다음 순서로이를 찾습니다.
현재 범위에 var foo의 정의가 있는지 여부.
함수 매개 변수에 foo 변수가 있는지 여부
함수 자체가 foo인지 여부.
외부 정의 도메인으로 이동하여 첫 번째 부분에서 찾아보기 시작하십시오.
네임 스페이스
가장 일반적인 문제 중 하나는 JavaScript에 전역 범위가 하나만 있기 때문에의 이름 지정 충돌입니다. 그러나이 문제는 익명 외부 기능으로 해결할 수 있습니다.
코드 사본은 다음과 같습니다.
(기능() {
// 자체 포함 된 "네임 스페이스"
window.foo = function () {
// 노출 된 폐쇄
};
}) (); // 함수를 즉시 실행합니다
위의 예에서 익명 기능은 표현식으로 간주되므로 실행됩니다.
코드 사본은 다음과 같습니다.
(// 부모님의 기능을 평가합니다
기능() {}
) // 함수 객체를 반환합니다
() // 평가 결과를 호출하십시오
물론 다른 방법을 사용하여 기능 표현, 다른 구조, 동일한 효과를 호출 할 수 있습니다.
코드 사본은 다음과 같습니다.
// 직접 호출하기위한 몇 가지 다른 스타일
!기능(){}()
+function () {} ()
(기능(){}());
// 등 ...
요약
익명의 외부 기능을 사용하여 코드를 공간에 캡슐화하는 것이 좋습니다. 이는 네임 스페이스 충돌을 해결할뿐만 아니라 프로그램의 모듈화를 용이하게합니다.
또한 글로벌 변수를 사용하는 것은 좋은 습관이 아니므로 유지 보수 비용이 높아지고 오류가 발생하기 쉽습니다.
네임 스페이스는 동일한 유형, 기능, 변수, 템플릿 등을 가지고 있으며 모두 엔티티에 속합니다.
엔티티의 주요 공통점은 이름을 가질 수 있다는 것입니다. (또한 태그에는 이름이있을 수 있지만 엔티티는 아닙니다.)
네임 스페이스 범위는 스코프의 일반적인 용어로 블록 범위, 클래스 범위, 기능 프로토 타입 범위 및 기능 스코프 (레이블에만 유효 함)와 평행합니다. 네임 스페이스 내에서 선언 된 이름은 네임 스페이스 범위에 있습니다. 글로벌 이름은 암시 적 글로벌 네임 스페이스 범위에서 고려됩니다.
네임 스페이스의 기능은 실제로 범위이지만 간단한 범위와 다릅니다. 여러 위치에서 동일한 네임 스페이스를 여러 번 선언 할 수 있지만 내부의 내용을 다시 정의 할 수 없습니다. 그들은 결국 STD, 매크로 정의와 마찬가지로 네임 스페이스를 어디에서나 종합 할 것입니다.