주요 내용:
1. JavaScript 어휘 범위의 의미 분석
2. 변수의 범위 체인을 구문 분석합니다.
3. 변수 이름이 승격되면 어떻게 되나요?
최근 Chuanzhi Podcast에서 JavaScript 강좌를 설명하고 있었는데 많은 친구들이 JavaScript가 너무 간단하다고 느꼈지만 사용법을 몰랐기 때문에 여러분과 공유할 콘텐츠를 준비했습니다.
이 시리즈에서는 범위 체인, 클로저, 함수 호출 패턴, 프로토타입 및 객체 지향 사항을 포함하여 JavaScript의 고급 부분을 주로 설명합니다. JavaScript의 기본 구문은 여기에 포함되지 않습니다. 기본 사항을 알아야 하는 학생들은 http로 이동하면 됩니다. : 학습용 무료 비디오를 다운로드하려면 //net.itcast.cn으로 이동하세요. 좋습니다. 더 이상 고민하지 말고 바로 주제로 넘어가겠습니다.
1. 블록 수준 범위 정보
JavaScript의 변수 범위에 대해 말하면 우리가 일반적으로 사용하는 C와 유사한 언어와 다릅니다.
예를 들어 C#의 다음 코드는 다음과 같습니다.
다음과 같이 코드 코드를 복사합니다.
정적 무효 Main(string[] args)
{
만약(사실)
{
정수 숫자 = 10;
}
System.Console.WriteLine(num);
}
이 코드를 컴파일하면 "현재 컨텍스트에 num이라는 이름이 존재하지 않습니다." 때문에 통과하지 못합니다.
변수의 범위는 중괄호로 제한되며 이를 블록 수준 범위라고 합니다.
블록 수준 범위에서 모든 변수는 정의 시작부터 중괄호 끝까지 정의의 중괄호 안에 있습니다.
이 범위 내에서는 사용할 수 있습니다. 즉, 코드에 액세스할 수 없습니다.
다음과 같이 코드 코드를 복사합니다.
만약(사실)
{
정수 숫자 = 10;
System.Console.WriteLine(num);
}
변수가 동일한 중괄호 내에서 정의되고 사용되기 때문에 여기에서 액세스할 수 있습니다.
하지만 JavaScript에서는 다릅니다. JavaScript에는 블록 수준 범위라는 개념이 없습니다.
2. JavaScript의 범위
JavaScript에서는 다음 코드를 사용합니다.
다음과 같이 코드 코드를 복사합니다.
만약(참) {
바넘 = 10;
}
경고(숫자);
작업 결과는 팝업 창입니다. 10. 그러면 JavaScript에서 변수의 범위는 어떻게 제한됩니까?
2.1 함수는 변수 범위를 제한합니다.
JavaScript에서는 함수만 변수의 범위를 제한할 수 있다는 것이 무슨 뜻인가요?
즉, JavaScript에서는 함수 내에 정의된 변수에 함수 내부에서 접근할 수 있지만 함수 외부에서 접근할 수 있습니다.
액세스할 수 없습니다. 다음 코드를 참조하세요.
다음과 같이 코드 코드를 복사합니다.
var func = 함수() {
바넘 = 10;
};
노력하다 {
경고(숫자);
} 잡기 ( 전자 ) {
경고(e);
}
이 코드가 실행되면 예외가 발생하고 num 변수가 정의되지 않습니다. 즉, 함수에 정의된 변수는 정의될 수 없습니다.
함수 외부에서 사용되는 것은 물론, 할당 이전에도 함수 내에서 자유롭게 사용할 수 있습니다.
다음과 같이 코드 코드를 복사합니다.
var func = 함수() {
경고(숫자);
바넘 = 10;
경고(숫자);
};
노력하다 {
기능();
} 잡기 ( 전자 ) {
경고(e);
}
이 코드가 실행된 후에는 오류가 발생하지 않으며 팝업 창이 정의되지 않음과 10으로 각각 두 번 나타납니다(이유는 아래에서 설명하겠습니다).
여기에서 볼 수 있듯이 변수는 함수 내에서만 액세스할 수 있습니다. 마찬가지로 함수 내의 함수에도 액세스할 수 있습니다.
2.2 하위 도메인은 상위 도메인에 액세스합니다.
앞서 언급했듯이 함수는 변수의 범위를 제한할 수 있으므로 함수의 함수는 하위 도메인에서 범위의 하위 도메인이 됩니다.
의 코드는 상위 도메인의 변수에 액세스할 수 있습니다. 다음 코드를 참조하세요.
다음과 같이 코드 코드를 복사합니다.
var func = 함수() {
바넘 = 10;
var sub_func = 함수() {
경고(숫자);
};
하위_펑크();
};
기능();
이 코드를 실행한 결과는 10 입니다. 위에서 언급한 변수 접근을 볼 수 있는데, 자식 도메인에서 부모 도메인에 접근하면 됩니다.
코드는 다음 코드와 같이 조건부이기도 합니다.
다음과 같이 코드 코드를 복사합니다.
var func = 함수() {
바넘 = 10;
var sub_func = 함수() {
바넘 = 20;
경고(숫자);
};
하위_펑크();
};
기능();
이 코드에는 이전보다 "var num = 20;"이 하나 더 있습니다. 이 코드는 하위 도메인에 있으므로 하위 도메인이 상위 도메인에 액세스합니다.
변경사항이 있어 이 코드로 출력한 결과는 20입니다. 즉, 이때 하위 도메인에서 접근한 num은 상위 도메인이 아닌 하위 도메인의 변수입니다.
JavaScript에서 변수를 사용할 때 먼저 JavaScript 인터프리터가 액세스에 대한 특정 규칙이 있음을 알 수 있습니다.
사용자 도메인을 검색하여 변수 정의가 있는지 확인하세요. 그렇다면 이 변수를 사용하세요. 그렇지 않으면 상위 도메인에서 변수를 검색하세요.
비유하자면, 최상위 범위를 아직 찾을 수 없을 때까지 "변수가 정의되지 않았습니다"라는 예외가 발생합니다. 다음 코드를 참조하세요.
다음과 같이 코드 코드를 복사합니다.
(기능() {
바넘 = 10;
(기능() {
바넘 = 20;
(기능(){
경고(숫자);
})()
})();
})();
이 코드가 실행된 후 "var num = 20;"이 제거되면 10이 인쇄됩니다.
"var num = 10"이면 정의되지 않은 오류가 발생합니다.
3. 범위 체인
JavaScript 범위를 분할하면 JavaScript 액세스 범위를 체인 트리 구조로 연결할 수 있습니다.
JavaScript의 범위 체인을 명확하게 이해하면 JavaScript의 변수와 클로저도 매우 명확해집니다.
다음 메서드에서는 그리기를 사용하여 범위 체인을 그립니다.
3.1 그리기 규칙:
1) 범위 체인은 객체의 배열입니다.
2) 모든 스크립트는 레벨 0 체인이며 각 개체는 하나의 위치를 차지합니다.
3) 체인으로 확장되는 기능을 볼 때마다 레벨별로 확장하십시오.
4) 접근 시 현재 함수를 먼저 살펴보고 정의되어 있지 않은 경우 체인을 확인합니다.
5) 레벨 0 체인까지 이를 반복합니다.
3.2 예
아래 코드를 보세요:
다음과 같이 코드 코드를 복사합니다.
바넘 = 10;
var func1 = 함수() {
바넘 = 20;
var func2 = 함수() {
바넘 = 30;
경고(숫자);
};
func2();
};
var func2 = 함수() {
바넘 = 20;
var func3 = 함수() {
경고(숫자);
};
func3();
};
func1();
func2();
이 코드를 분석해 보겠습니다.
-> 우선, 전체 코드는 전역 범위이며 레벨 0 범위 체인으로 표시될 수 있습니다. 그 다음에는 배열이 있습니다.
var link_0 = [num, func1, func2];//여기에는 의사 코드로 설명되어 있습니다.
-> 여기서 func1과 func2는 모두 함수이므로 두 개의 레벨 1 범위 체인이 파생됩니다.
var link_1 = { func1: [ num, func2 ] } // 여기에 의사 코드로 설명됨
var link_1 = { func2: [ num, func3 ] } // 여기에 의사 코드로 설명됨
-> 첫 번째 레벨 1 체인은 레벨 2 체인에서 파생됩니다.
var link_2 = { func2: [ num ] } // 여기에는 의사 코드로 설명되어 있습니다.
-> 두 번째 레벨 1 체인은 정의된 변수가 없으며 빈 체인이며, 이는 다음과 같이 표현됩니다.
var link_2 = { func3: [ ] };
-> 위의 코드를 통합하면 스코프 체인은 다음과 같이 표현될 수 있습니다.
다음과 같이 코드 코드를 복사합니다.
//여기서는 의사 코드로 설명합니다.
var link = [ // 레벨 0 체인
숫자,
{ func1 : [ // 첫 번째 레벨 1 체인
숫자,
{ func2 : [ // 레벨 2 체인
숫자
] }
]},
{ func2 : [ // 두 번째 레벨 1 체인
숫자,
{ func3 : [] }
]}
];
-> 이미지로 표현하면 다음과 같다.
그림: 01_01 범위 체인.bmp
참고: 체인 다이어그램을 표현하려면 js 코드를 사용하고 강조 표시하면 매우 명확해집니다.
이 범위 체인 다이어그램을 사용하면 변수 액세스가 수행되는 방법을 명확하게 이해할 수 있습니다.
변수를 사용해야 할 경우 먼저 현재 체인에서 변수를 검색하세요. 찾으면 직접 사용하세요.
위쪽으로 검색하고, 찾지 못한 경우 0레벨 범위 체인까지 한 수준 범위 체인을 검색합니다.
변수가 속한 범위 체인의 수준을 매우 명확하게 결정할 수 있다면 JavaScript를 분석할 때
클로저와 같은 고급 JavaScript 기능을 코딩하고 사용하는 것은 매우 쉽습니다(적어도 저에게는).
3. 변수 이름 승격 및 함수 이름 승격
범위 체인과 변수 액세스 규칙에는 매우 까다로운 문제가 있습니다. 먼저 다음을 살펴보겠습니다.
자바스크립트 코드:
다음과 같이 코드 코드를 복사합니다.
바넘 = 10;
var func = 함수() {
경고(숫자);
바넘 = 20;
경고(숫자);
};
기능();
실행 결과는 어떻게 될까요? 생각해보시면 됩니다. 아직 답은 공개하지 않겠습니다.
먼저 이 코드를 분석해 보겠습니다.
이 코드에는 num 및 func 멤버를 포함하는 레벨 0 범위 체인이 있습니다. func 아래에는 레벨 1 함수가 있습니다.
num 멤버를 포함하는 도메인 체인 따라서 func 함수를 호출하면 현재 범위에서 감지됩니다.
변수 num이 정의되었으므로 이 변수가 사용됩니다. 그러나 코드가 num에 값을 할당하지 않습니다.
코드는 위에서 아래로 실행되므로 첫 번째 인쇄는 정의되지 않고 두 번째 인쇄는 20입니다.
제대로 이해하셨나요?
JavaScript에서는 이렇게 뒤에서 코드를 정의하고 앞에서 사용하는 것도 흔한 일입니다.
질문. 이때는 처음에 변수를 정의한 것과 같으며, 결과는 다음과 같습니다.
다음과 같이 코드 코드를 복사합니다.
바넘 = 10;
var func = 함수() {
var num;// 여기에 정의한 것 같지만 할당이 없습니다.
경고(숫자);
바넘 = 20;
경고(숫자);
};
기능();
이 현상을 흔히 변수 이름 승격이라고 합니다. 예를 들어 다음 코드는 다음과 같습니다.
다음과 같이 코드 코드를 복사합니다.
var func = 함수() {
Alert("외부 함수 호출");
};
var foo = 함수() {
기능();
var func = 함수() {
Alert("내부 함수 호출");
};
기능();
};
좋아요, 이 코드는 어떻게 생겼나요? 아니면 뭔가 다른 것이 있어야 하는데, 독자들의 생각에 맡기지 않겠습니다!
다음 글에서 답을 드리겠습니다.
이러한 차이로 인해 실제 개발 시에는 모든 변수를 처음부터 작성하는 것이 좋습니다.
즉, 변수는 C 언어의 조항과 유사하게 함수 시작 부분에 정의됩니다. 이는 js 라이브러리에서도 마찬가지입니다.
이는 jQuery 등으로 수행됩니다.
4. 요약
좋아요, 이 글에서는 주로 JavaScript의 어휘 범위가 무엇인지, 그리고 그에 대한 설명이 무엇인지 설명합니다.
스코프 체인과 변수의 접근 상태를 어떻게 분석하는지 한 번 더 연습해 볼까요? ! !
아래 코드를 실행한 결과가 무엇인지 확인하세요.
다음과 같이 코드 코드를 복사합니다.
if( ! 창의 "a" ) {
var a = "변수 정의";
}
경고(a);