1.ES6之前
在ES6之前,Javascript只有全局作用域和函数作用域,定义变量也是用var关键字。
var a = 5;
function fn() {
console.log(a); // 5
}
fn() // fn函数能访问到全局作用域下的a变量
因为没有块级作用域,所以在块级作用域中的变量相当于全局作用域中的变量
{
var a = 5
}
console.log(a); // 5
在for循环中
for(var i = 0;i < 10;i++) {
}
console.log(i); // 10
这种情况更适合以下方式编写
var i;
for(i = 0;i < 10;i++) {
}
console.log(i); // 10
不同作用域中,会就近取变量的值
var a = 10;
function fn() {
var a = 5;
console.log(a); // 5
}
fn()
如果在最近的作用域中没有取到变量,会向上级作用域中继续搜索变量,直到全局作用域
var a = 10;
function fn() {
console.log(a); // 10
}
fn()
不同函数之间的变量不能直接访问,因为属于不同的作用域
var a = 10;
function aa() {
console.log(a);
}
function bb() {
var a = 20;
aa()
}
bb() // 10
以上代码中得到的结果是10,因为aa函数中不能访问bb中a变量的值
2.ES6之后
在ES6之后,Javascript引入了块级作用域,也可以使用let关键字定义变量
for(var i = 0;i < 10;i++) {
}
console.log(i); // 10
for(let j = 0;j < 10;j++) {
}
console.log(j); // j is not defined
以上就是有无块级作用域的区别,没有块级作用域时,for循环中定义的变量得到提升,因此全局作用域中可以访问到。有块级作用域时,变量j只对for循环内部有效,因此全局作用域访问不到变量j