作用域就是变量的作用范围。也就是你声明一个变量以后,这个变量可以在什么场合下使用。以前的JavaScript只有全局作用域,和函数作用域。

作用域就是变量的作用范围。也就是你声明一个变量以后,这个变量可以在什么场合下使用。以前的JavaScript只有全局作用域,和函数作用域。

var的问题

1.var 没有块级作用域,定义后在当前包中都都可以访问,如果变量名重复,就会覆盖前面定义的变量,并且很可以被他人修改。

1
2
3
4
if(true){
var a = "a"; //期望a是某一个值
}
console.log(a);


2.var 在for循环标记变量共享,一般在循环中会使用的i会被共享,其本质也是由于没有块级作用域造成的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
for (var i = 0; i < 3; i++) {
setTimeout(function () {
alert(i);
}, 0);
}

// 结果就是 弹窗三次 3

for ( i = 0; i < 3; i++) {
setTimeout(function () {
alert(i);
}, 0);
}

// 结果就是 弹窗三次 0-2

块级作用域

在用var定义变量的时候,变量通过闭包进行隔离的,现在用了let,不仅仅可以通过闭包隔离,还可以增加了一些块级作用域隔离。块级作用用一组大括号定义一个快,使用let定义的变量字啊大括号的外面是访问不到的。

实现会计作用域

1
2
3
4
5
if(ture){
let name = 'wjh'
}

consloe.log('name'); // ReferenceError: name is not defined

不会污染全局对象


1
2
3
4
if(ture){
let name = 'wjh'
}
console.log(window.name); // undefined

for 循环中也可以使用i


1
2
3
4
5
6
7
8
9
// 嵌套循环不会相互影响
for (let i = 0; i < 3; i++) {
console.log("out", i);
for (let i = 0; i < 2; i++) {
console.log("in", i);
}
}

// 结果 out 0 in 0 in 1 out 1 in 0 in 1 out 2 in 0 in 1

重复定义会报错

1
2
3
4
if(ture){
let a = 1;
let a = 2; //Identifier 'a'
}

不存在变量的预解释

1
2
3
4
5
6
for(let i = 0;i<2;i++){
console.log('inner',i);
let i =100;
}

// 结果 i is not defined

闭包的新写法

1
2
3
;(function(){

})();

现在

1
2
3
{

}