for (var i = 0; i< 10; i++){
setTimeout(() => {
console.log(i);
}, 1000)
}
1、
原理:
利用 setTimeout 函数的第三个参数,会作为回调函数的第一个参数传入 利用 bind 函数部分执行的特性 代码 1:
for (var i = 0; i < 10; i++) {
setTimeout(i => {
console.log(i);
}, 1000, i)
}
代码 2:
for (var i = 0; i < 10; i++) {
setTimeout(console.log, 1000, i)
}
代码 3:
for (var i = 0; i < 10; i++) {
setTimeout(console.log.bind(Object.create(null), i), 1000)
}
2、
原理:
构建出块级作用域。
代码 1:
for (var i = 0; i < 10; i++) {
(i => {
setTimeout(() => {
console.log(i);
}, 1000)
})(i)
}
代码 2:
for (var i = 0; i < 10; i++) {
try {
throw new Error(i);
} catch ({
message: i
}) {
setTimeout(() => {
console.log(i);
}, 1000)
}
}
代码 3:
for(var i = 0; i < 10; i++){
try{
throw i;
}catch(i){
setTimeout(() => { console.log(i); },1000)
}
}
3、
原理:
很多其它的方案只是把 console.log(i) 放到一个函数里面,因为 setTimeout 函数的第一个参数只接受函数以及字符串,如果是 js 语句的话,js 引擎应该会自动在该语句外面包裹一层函数
代码 1:
for (var i = 0; i < 10; i++) {
setTimeout(console.log(String(i)), 1000)
}
代码 2:
for (var i = 0; i < 10; i++) {
setTimeout((() => {
console.log(i);
})(), 1000)
}
代码 3:
for (var i = 0; i < 10; i++) {
setTimeout((i => {
console.log(i);
})(i), 1000)
}
代码 4:
for (var i = 0; i < 10; i++) {
setTimeout((i => {
console.log(i);
}).call(Object.create(null), i), 1000)
}
代码 5:
for (var i = 0; i < 10; i++) {
setTimeout((i => {
console.log(i);
}).apply(Object.create(null), [i]), 1000)
}
代码 6:
for (var i = 0; i < 10; i++) {
setTimeout((i => {
console.log(i);
}).apply(Object.create(null), { length: 1, '0': i }), 1000)
}
4、
原理:
利用 eval 或者 new Function 执行字符串,然后执行过程同方法四
代码 1:
for (var i = 0; i < 10; i++) {
setTimeout(eval('console.log(i)'), 1000)
}
代码 2:
for (var i = 0; i < 10; i++) {
setTimeout(new Function('i', 'console.log(i)')(i), 1000)
}
代码 3:
for (var i = 0; i < 10; i++) {
setTimeout(new Function('console.log(i)')(), 1000)
}