Block-level Scope Binding
Previous variable declarations with var were considered to be declared at the top of the scope, regardless of where they were declared. Since functions are first-class citizens, the order is generally function functionName(), var variable.
Block Declarations
Block declarations are used to declare variables that are not accessible outside the scope of a given block. Block scope exists in:
- Inside functions
- Inside blocks (the area between characters and
{and})
Temporal Dead Zone
When the JavaScript engine scans code and finds variable declarations, it either hoists them to the top of the scope or places them in the TDZ. Accessing variables in the TDZ will trigger a runtime error. Variables are only removed from the TDZ after their declaration has been executed, after which they can be accessed normally.
if(condition){
console.log(typeof value) // 引用错误
let value = "blue";
}
// 以下的value并不在TDZ中
console.log(typeof value); // "undefined"
if(condition){
let value="blue"
}
Block-level Scope Binding in Loops
When using let, the variable only exists within the for loop. Once the loop ends, the variable cannot be accessed.
for(let i=0;i<10;i++){
process(items[i]);
}
// i 在这里不可访问,抛出一个错误
console.log(i);
Functions in Loops
var declarations make it exceptionally difficult for developers to create functions within loops, because the variable remains accessible outside the loop.
var funs = [];
for(var i=0;i<10;i++){
funs.push(function(){
console.log(i)
})
}
funcs.forEach(function(func){
func(); // 输出10次数字10
})
To solve this problem, developers use Immediately Invoked Function Expressions (IIFEs) within loops to force the creation of copies of the counter variable. The IIFE creates a copy for each variable `i` it accepts and stores it as the variable `value`. The value of this variable is the value used by the function created in the corresponding iteration, thus calling each function.
var funs = [];
for(var i=0;i<10;i++){
funs.push((function(value){
return function(){
console.log(i)
}
})(i))
}
funcs.forEach(function(func){
func(); // 输出0,1,2...
})
let Declarations in Loops
let declarations simplify the looping process by mimicking everything described above. Each iteration of the loop creates a new variable and initializes it with the value of the variable of the same name from the previous iteration. This also applies to for-in, for-of, and for-each loops.
var funs = [];
for(let i=0;i<10;i++){
funs.push(function(){
console.log(i)
})
}
funcs.forEach(function(func){
func(); // 输出0,1,2...
})
It is crucial to understand that the behavior of `let` declarations within loops is specifically defined in the standard and is not necessarily related to `let`'s non-hoisting characteristic. In fact, early `let` implementations did not include this behavior; it was added later.
Using const in Loops
In for(const i=0;i<10;i++), an error will occur because i++ attempts to change the value of the constant `i`. However, in for-in and for-of loops, there is no operation that attempts to change the original value of `i`; instead, a new variable is created. Therefore, the execution will be the same as using a let declaration.
Global Scope Binding
Another difference between let and const and var is their behavior in the global scope. When `var` is used in the global scope, it creates a new global variable as a property of the global object. This means `var` is very likely to unintentionally overwrite an existing global variable. However, using let and const cannot overwrite global variables; they can only shadow them. So,
let RegExp = 'Hello world'
console.log(window.RegExp === RegExp)
主题测试文章,只做测试使用。发布者:Walker,转转请注明出处:https://walker-learn.xyz/archives/4308