初始问题
console.log('start')
for (var i = 0; i < 3; i++) {
setTimeout(function () {
console.log(i)
}, 1000);
}
console.log('end')
// start end
// 1s 后 3 3 3
执行顺序:
start
i is undefined
end
i == 3
function
i == 3
function
i == 3
function
i == 3
改法一 根据es6块级作用域更改
见下文作用域解析。
var i
是全局作用域,更改为es6的块级作用域。
console.log('start')
for (let i = 0; i < 3; i++) {
setTimeout(function () {
console.log(i)
}, 1000);
}
console.log('end')
// start end
// 1s 后 1 2 3
改法二 根据函数作用域更改
for (var i = 0; i < 5; i++) {
(function test(args){
setTimeout(function() {
console.log(args)
}, 1000);
})(i)
}
立即执行函数,每个立即执行函数都是单独的作用域。
改法三 setTimeout 的第 3+ 个参数
for (var i = 0; i < 5; i++) {
setTimeout(function (i) {
console.log(i)
}, 1000, i);
}
js作用域
- es5作用域:全局作用域、函数作用域
- es6作用域:全局作用域、函数作用域、块级作用域
es5作用域
var out1 = "out1"; //全局作用域
out2 = "out2"; //全局作用域
function fn1(){
var inner1 = "inner1" //函数作用域
inner2 = "inner2" //全局作用域
window.inner3 = "inner3" //全局作用域
}
if(true) {
var block1 = "block1" //全局作用域
}else {
var block2 = "block2" //全局作用域
}
console.log(out1) //out1
console.log(out2) //out2
console.log(inner1) //inner1 is not defined
console.log(inner2) //inner2 is not defined
console.log(inner3) //inner3 is not defined
fn1();
console.log(inner1) //inner1 is not defined
console.log(inner2) //inner2
console.log(inner3) //inner3
console.log(block1) //block1
console.log(block2) //undefined
es6块级作用域
var dead = "dead1"
if(true) {
// dead的暂时性死区
console.log(dead) //Cannot access 'dead' before initialization
let dead = "dead2"
let block1 = 'block1'
} else {
let block2 = 'block2'
}
console.log(block1) //block1 is not defined
console.log(block2) //block2 is not defined
console.log(dead) //dead1
如果let声明的变量没有变量提升,应该打印dead1
;而他却报错,说明它是提升了的,只是规定了不能在其声明之前使用而已。我们称这特性叫“暂时性死区(temporal dead zone)