Home  >  Article  >  Web Front-end  >  In-depth understanding of JavaScript advanced lexical scope and scope chain_Basic knowledge

In-depth understanding of JavaScript advanced lexical scope and scope chain_Basic knowledge

WBOY
WBOYOriginal
2016-05-16 17:09:511007browse

Main content:
1. Analyze the meaning of JavaScript lexical scope

2. Parse the scope chain of variables

3. What happens when the variable name is promoted?

Recently, I was explaining JavaScript courses on Chuanzhi Podcast. Many friends felt that JavaScript is so simple, but they don’t know how to use it, so I prepared some content to share with you.
This series mainly explains The advanced parts of JavaScript include scope chains, closures, function calling patterns, prototypes and object-oriented things. The basic syntax of JavaScript is not included here. If you need to know the basics, students can go to http://net. Go to itcast.cn to download free videos for learning. Okay, without further ado, let’s go directly to our topic.

1. About block-level scope
When it comes to JavaScript variable scope, it is different from the C-like language we usually use.
For example, in C#, the following Code:

Copy code The code is as follows:

static void Main(string[] args)
{
if(true)
{
int num = 10;
}
System.Console.WriteLine(num);
}

If this code is compiled, it will not pass because "the name num does not exist in the current context". Because the scope of the variable here
is limited by curly braces, it is called block-level scope.

In the block-level scope, all variables are within the curly braces of the definition. They can be used within the
range from the beginning of the definition to the end of the curly braces. They cannot be accessed outside this range. In other words, the code

Copy code The code is as follows:

if(true)
{
int num = 10;
System.Console.WriteLine(num);
}

It can be accessed here because the definition and use of variables are within the same curly braces.

But it is different in JavaScript. There is no concept of block-level scope in JavaScript.

2. Scope in JavaScript
In JavaScript, the following code:

Copy code The code is as follows:

if(true) {
var num = 10 ;
}
alert(num);

The result of the operation is a pop-up window 10. So how is the scope of variables limited in JavaScript?

2.1 Function limits variable scope
In JavaScript, only functions can limit the scope of a variable. What does that mean?
That is to say, in JavaScript, variables defined within a function can be accessed within the function, but
cannot be accessed outside the function. See the following code:

Copy code The code is as follows:

var func = function() {
var num = 10;
};
try {
alert(num);
} catch ( e ) {
alert( e );
}

When this code is run, an exception will be thrown. The variable num is not defined. In other words, variables defined in the function cannot
be used outside the function. Of course, they can be used freely within the function, even if Before assigning value. Look at the following code:

Copy the code The code is as follows:

var func = function( ) {
alert(num);
var num = 10;
alert(num);
};
try {
func();
} catch ( e ) {
alert( e );
}

After this code is run, no error will be thrown. The window will pop up twice, undefined and 10 (as for why, explained below).

It can be seen from here that variables can only be accessed within a function. Similarly, functions within this function can also be accessed.


2.2 Child domain accesses parent domain
As mentioned earlier, a function can limit the scope of a variable, then the function in the function becomes a subdomain of the scope. In the child Code in domain
can access variables in the parent domain. See the code below:

Copy code The code is as follows:

var func = function() {
var num = 10;
var sub_func = function() {
alert(num);
};
sub_func();
};
func();

The result of executing this code is 10. You can see the variable access situation mentioned above. However, accessing the
code of the parent domain in the child domain is also conditional. As shown in the following code:

Copy code The code is as follows:

var func = function() {
var num = 10;
var sub_func = function() {
var num = 20;
alert(num);
};
sub_func();
};
func();

This code has one more "var num = 20;" than the previous one. This code is in the subdomain, so the situation of the subdomain accessing the parent domain has
changed. This code prints The result is 20. That is, the num accessed by the subdomain at this time is a variable in the subdomain, not the parent domain.

It can be seen that there are certain rules for access. When using variables in JavaScript, the JavaScript interpreter first searches for the definition of the variable in the current
scope. If so, this variable is used; if not Just look for the variable in the parent domain.
And so on, until the top-level scope is still not found, an exception "Variable is not defined" will be thrown. Look at the following code:

Copy code The code is as follows:

(function() {
var num = 10;
(function() {
var num = 20;
(function(){
alert(num);
})()
})();
})();

After executing this code, 20 will be printed. If "var num = 20;" is removed, then 10 will be printed. Similarly, if
"var num = 10" is removed, undefined will appear. Error.

3. Scope chain
With the division of JavaScript scopes, JavaScript access scopes can be connected into a chained tree structure.
Once the scope chain of JavaScript can be clearly understood, then the variables and closures of JavaScript will be very clear.
The following uses drawing methods to draw the scope chain.

3.1 Drawing rules:
1) The scope chain is an array of objects
2) All scripts are level 0 chains, and each object occupies a position
3) Whenever you look at When the function extends a chain, expand it level by level
4) When accessing, first look at the current function. If it is not defined, check the upper level chain
5) Repeat until the level 0 chain

3.2 Example
Look at the following code:

Copy code The code is as follows:

var num = 10;
var func1 = function () {
var num = 20;
var func2 = function() {
var num = 30;
alert(num);
};
func2();
};
var func2 = function() {
var num = 20;
var func3 = function() {
alert(num);
};
func3( );
};
func1();
func2();

Let’s analyze this code:
-> First of all, the entire code is a global scope, which can be marked as a level 0 scope chain. Then there is an array
var link_0 = [num, func1 , func2 ];// Use pseudo code to describe here
-> Here func1 and func2 are both functions, so two level 1 scope chains are derived, respectively
var link_1 = { func1: [ num, func2 ] };// Use pseudo code to describe here
var link_1 = { func2: [ num, func3 ] };// Use pseudo code to describe here
-> The first level 1 chain derives level 2 Chain
var link_2 = { func2: [ num ] };// Use pseudo code to describe
-> The second level 1 chain has no variables defined and is an empty chain, so it is represented as
var link_2 = { func3: [ ] };
-> Integrating the above code, the scope chain can be expressed as:

Copy code The code is as follows:

// This is described with pseudo code
var link = [ // Level 0 chain
num,
{ func1 : [ // The first level 1 chain
num,
{ func2 : [ // Level 2 chain
num
] }
]},
{ func2 : [ // The first level chain Two level 1 chains
num,
{ func3 : [] }
]}
];

-> 이미지로

로 표현

In-depth understanding of JavaScript advanced lexical scope and scope chain_Basic knowledge

사진: 01_01 스코프체인.bmp

참고: js 코드를 사용하여 체인 다이어그램을 표현하면 강조 표시되면 매우 명확해집니다.

이 스코프 체인 다이어그램을 사용하면 변수에 액세스하는 방법을 명확하게 이해할 수 있습니다.
변수를 사용해야 할 경우 먼저 현재 체인에서 변수를 찾고, 찾으면 직접 사용하세요. .
다시 검색하지 않으며, 찾지 못한 경우에는 0레벨 범위 체인까지 검색합니다.

변수가 속하는 스코프 체인의 수준을 명확하게 결정할 수 있다면 JavaScript
코드를 분석하고 클로저와 같은 고급 JavaScript 기능을 사용할 때 매우 쉬울 것입니다(적어도 나에게는).

3. 변수명 승격 및 함수명 승격

스코프 체인과 변수 액세스 규칙에는 매우 까다로운 문제가 있습니다. 먼저 아래

의 JavaScript 코드를 살펴보세요.

코드 복사 코드는 다음과 같습니다.
var num = 10;
var func = 함수() {
경고(숫자);
var num = 20;
경고(숫자);
};
func();

실행 결과는 어떻게 될까요? 생각해 보세요. 아직 답은 공개하지 않겠습니다.

먼저 이 코드를 분석해 보겠습니다.

이 코드에는 num 및 func 멤버가 있는 레벨 0 범위 체인이 있습니다. func 함수가 호출되면
변수 num이 현재 범위에 정의되어 있으므로 이 변수가 사용되는 것으로 감지됩니다. 그러나
코드가 다음과 같기 때문에 이때 num에는 값이 할당되지 않습니다. 위에서 아래로 실행되므로 첫 번째 인쇄는 정의되지 않고 두 번째 인쇄는 20입니다.
답을 맞히셨나요?

이런 코드를 뒤에서 정의하고 이를 앞에서 사용하는 것도 자바스크립트에서 흔히 발생하는

문제입니다. 이때 변수를 처음에 정의한 것처럼 결과는 이렇습니다. 다음 코드:



var num = 10;
var func = function() {
var num; // 여기에 정의된 것 같지만 할당이 없습니다.
Alert(num);
var num = 20;
경고(숫자);
};
func();


그러면 이 현상을 흔히 변수 이름 승격이라고 합니다. 예를 들어 다음 코드는


var func = function() {
Alert("외부 함수 호출");
};
var foo = function( ) {
func();

var func = function() {
Alert("내부 함수 호출");
};

func();
};


그럼 이 코드의 결과는 무엇인가요? 아니면 뭔가 다른게 있을텐데, 독자들에게 생각을 맡기지 않겠습니다. 다음 글에서 답변해드리겠습니다

.
이러한 차이로 인해 실제 개발 시에는 모든 변수를 처음에 작성하는 것이 좋습니다.

즉, 변수는 C언어의 규정과 유사하게 함수 시작 부분에 정의됩니다. jQuery 등과 같은 js 라이브러리

에서도 수행됩니다.

4. 요약 자, 이번 글에서는 주로 JavaScript의 어휘 범위가 무엇인지 설명하고,

범위 체인과 변수 액세스를 분석하는 방법을 설명합니다. 마지막으로 한 가지 연습으로 마무리하겠습니다. ! !


다음 코드를 실행한 결과를 보세요.


코드를 복사하세요. 코드는 다음과 같습니다.
if ( ! "a" in window ) {
var a = "변수 정의";
}
alert(a);


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn