第 31 题:改造下面的代码,使之输出 0 - 9,写出你能想到的所有解法。
js
for (var i = 0; i < 10; i++) {
setTimeout(() => {
console.log(i);
}, 1000);
}
let
信息
利用 let
变量的特性 — 在每一次 for
循环的过程中,let
声明的变量会在当前的块级作用域里面(for
循环的 body
体,也即两个花括号之间的内容区域)创建一个文法环境(Lexical Environment
),该环境里面包括了当前 for
循环过程中的 i
js
for (let i = 0; i < 10; i++) {
setTimeout(() => {
console.log(i);
}, 1000);
}
IIFE 立即执行函数
信息
利用函数自执行的方式,把当前 for
循环过程中的 i
传递进去,构建出块级作用域。
js
for (var i = 0; i < 10; i++) {
((j) => {
setTimeout(() => {
console.log(j);
}, 1000);
})(i);
}
setTimeout
信息
setTimeout
函数的第三个参数,会作为回调函数的第一个参数传入
- 代码 1:
js
for (var i = 0; i < 10; i++) {
setTimeout(
(i) => {
console.log(i);
},
1000,
i
);
}
- 代码 2:
js
for (var i = 0; i < 10; i++) {
setTimeout(console.log, 1000, i);
}
- 代码 3:
js
for (var i = 0; i < 10; i++) {
setTimeout(
(() => {
console.log(i);
})(),
1000
);
}
- 代码 4:
js
for (var i = 0; i < 10; i++) {
setTimeout(
((j) => {
console.log(j);
})(i),
1000
);
}
- 代码 5:
js
for (var i = 0; i < 10; i++) {
setTimeout(
((j) => {
console.log(j);
}).call(Object.create(null), i),
1000
);
}
- 代码 6:
js
for (var i = 0; i < 10; i++) {
setTimeout(
((j) => {
console.log(j);
}).apply(Object.create(null), [i]),
1000
);
}
bind 特性
js
for (var i = 0; i < 10; i++) {
setTimeout(console.log.bind(Object.create(null), i), 1000);
}
try catch 块级作用域
js
for (var i = 0; i < 10; i++) {
try {
throw i;
} catch (i) {
setTimeout(() => {
console.log(i);
}, 1000);
}
}
eval 和 new Function
信息
利用 eval 或者 new Function 执行字符串
- 代码 1:
js
for (var i = 0; i < 10; i++) {
setTimeout(eval("console.log(i)"), 1000);
}
- 代码 2:
js
for (var i = 0; i < 10; i++) {
setTimeout(new Function("console.log(i)")(), 1000);
}
- 代码 3:
js
for (var i = 0; i < 10; i++) {
setTimeout(new Function("j", "console.log(j)")(i), 1000);
}