什么是作用域?
作用域可以理解为某个变量在某个范围内是可以访问到。
var是函数作用域(声明的函数内)、全局作用域(在哪里都可以访问到)
let是块级作用域(即程序中的大括号{}包含的范围内)
看下面的例子:
console.log("---------------------"); { var c = 100; } console.log(c); { let c = 10; console.log("block area ", c); } console.log(c); console.log("======================");看以上示例中输出的两个100都是输出的var声明的变量c,因为var声明的是函数作用域或全局作用域(在这里是全局的),所以输出发的时候是100;
而let声明的是块级作用域,即只在大括号内有效{},所以只有在大括号内输出的才是10,即使大括号外有输出这个变量,也不能输出这个块里面的值。
再看下面的例子:
function test() { for (var i = 0; i < 10; i++) { setTimeout(() => { console.log(i); }, 0); } } test(); function test1() { for (var i = 0; i < 10; i++) { (function (index) { setTimeout(function () { console.log(index); }, 0); })(i); } } test1(); function test2() { for (let i = 0; i < 10; i++) { setTimeout(() => { console.log(i); }, 0); } } test2();这个有点绕,
test函数中使用的是var,是函数作用域,而setTimeout是异步函数,for的循环执行完了(这里是同步执行的),最后i变成了10,而setTimeout会在同步函数后执行,所以最后输出了函数作用域内的变量i,即10.
test1函数中也是使用的var,但是输出正常,这里有一个区别是使用了立即执行函数,即内部有一个function,这里把var的参数传给了index,而index是在这个内部函数作用域内有效,这个在书面上理解为捕获了i的值。即把i的值给了index,index是函数作用域内的,异步setTimeout执行的时候 ,输出了内部函数中的index的值。(这个是我个人的理解啊,有误差的大家可以指正)
test2函数中使用的是let,这个是块级作用域,即{}捕获了i的值。可以避免var声明引起的问题。在未来的工作中要尽量使用let。避免出现上面说的问题。