Home  >  Article  >  Web Front-end  >  About inference of variable scope of var declaration in JavaScript_javascript skills

About inference of variable scope of var declaration in JavaScript_javascript skills

WBOY
WBOYOriginal
2016-05-16 18:13:37885browse
1. Myth! Doubts caused by a piece of code
Please look at the following code:
Copy the code The code is as follows:

for(var i=0;i<3;i ) {
console.log(j "," k);
for(var j=0;j<3;j ) {
var k = j 1;
}
}
console.log(i);

Output result:
undefined,undefined
3, 3
3,3
3
If you are working in C, Java and other languages, you may wonder why local variables like j and k can be accessed by code outside the scope?
If a variable declared with var in JavaScript can be regarded as a local variable, then the scope that can access the variable is the local scope of the variable. As in the above example, at the console.log line, there are still scopes of j and k, and outside the loop, there is still the scope of i. At this point, perhaps I can arbitrarily say that JavaScript has no real local scope. Really? No!

2. How to obtain the real local scope? A writing method caught my attention
You may have seen the source code of JQuery or the source code of Ext, and you may be a little familiar with the following writing method.
Copy code The code is as follows:

var a = 3,b=4;
var exports = (function() {
var a = 1,b=2;
return {a:a,b:b};
})();
console.log(" " a "," b);
console.log(exports.a "," exports.b);

Output results:
3,4
1,2
It is a very amazing discovery (actually it is not amazing, everyone knows it) that there is an independent scope inside the function, that is, the variables declared by var inside the function can only be used inside the function. Therefore, every master in each framework writes like this to prevent conflicts between local variables and external variables (outer local variables and global variables).
At this point, I retract the arbitrary inference in the first article and modify it:
JavaScript is bounded by functions, and each function has a local scope; any other block (including ordinary code blocks, for loops, If, while and other code blocks) do not have a local scope. Variables declared using var can directly pass through these code blocks and can be accessed by external code.


3. When is an error reported and when is it undefined? The declaration mechanism of var
Look at the code:
Copy the code The code is as follows:

console.log(a)

Output result:
ReferenceError: a is not defined
Output result:
undefined
Copy code The code is as follows:

var exports = (function() {
var a = 1,b=2;
return {a:a,b:b};
})();
console.log(a);

Output result:
ReferenceError: a is not defined
Conjecture:
Every time the JavaScript engine executes code, it will first scan all the code in the scope (the code inside the function in the scope will not be scanned), and record all the variables declared by var. Before the code is executed and assigned, the values ​​of these variables are undefined. After that, if you access a variable, you will first access the local variable. If there is no such local variable, you will access the local variable of the upper level (such as a closure, and the upper level creates an environment for the closure) until the complete global variable is accessed. If there is no such variable, an exception is thrown.


4. Digression: closure is asynchronous, variable values ​​are messed up! How to ensure the transfer of the current value of local variables in asynchronous situations?
Let’s talk about the code:
Copy the code The code is as follows:

for( var i=0;i<3;i ) {
setTimeout(function() {
console.log(i);
},1);
}

Output result:
3
3
3
Why? Because when the closure is executed asynchronously, i always accesses i in the outer scope. Since it is asynchronous, the loop has ended when the closure is executed, and i is already 3, so every time it is printed It's 3.
So how to solve this problem? We need to convert i into a local variable.
Well, someone has this way of writing:
Copy the code The code is as follows:

for(var i=0;i<3;i ) {
var j = i;
setTimeout(function() {
console.log(j);
},1);
}

Output result:
2
2
2
Why?
Actually, as explained before, the scopes of j and i are actually the same. They are all outer local variables. When the loop execution is completed in an asynchronous situation, j is 2 (i is one less than i);
What should we do? (Please imagine an advertisement, (⊙v⊙)).
As we all know, parameters in a function are also considered local variables of the function. So here is a way to convert local variables into actual parameters of the function, thus achieving the effect of value transfer.
Copy code The code is as follows:

for(var i=0;i<3;i ) {
setTimeout((
function(j){
return function() {
console.log(j);
}
})(i)
, 1);
}

Output
0
1
2
In fact, after saying so much, you will almost understand it after writing the code. Use this This anonymous function method eliminates the problem of variable changes in asynchronous situations, but this is a digression from this post.

Summary:
Um. I won’t write it anymore, I’m too lazy, I’ll find time to make it up one day. hey-hey.
In fact, these conclusions should be written in the RFC. But chewing on English documents. . . Forget it. . I deduced it myself. Haha, don’t laugh at the sight of it.
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