Giter VIP home page Giter VIP logo

Comments (66)

 avatar commented on May 16, 2024 368

解决办法汇总

  • 方法一

    原理:

    • 利用 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)
    }
  • 方法二

    原理:

    • 利用 let 变量的特性 — 在每一次 for 循环的过程中,let 声明的变量会在当前的块级作用域里面(for 循环的 body 体,也即两个花括号之间的内容区域)创建一个文法环境(Lexical Environment),该环境里面包括了当前 for 循环过程中的 i具体链接

    代码 1:

    for (let i = 0; i < 10; i++) {
      setTimeout(() => {
        console.log(i);
      }, 1000)
    }

    等价于

    for (let i = 0; i < 10; i++) {
      let _i = i;// const _i = i;
      setTimeout(() => {
        console.log(_i);
      }, 1000)
    }
  • 方法三

    原理:

    代码 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)
      }
    }
  • 方法四

    原理:

    • 很多其它的方案只是把 console.log(i) 放到一个函数里面,因为 setTimeout 函数的第一个参数只接受函数以及字符串,如果是 js 语句的话,js 引擎应该会自动在该语句外面包裹一层函数

    代码 1:

    for (var i = 0; i < 10; i++) {
      setTimeout(console.log(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)
    }
  • 方法五

    原理:

    • 利用 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)
    }

from daily-interview-question.

jefferyE avatar jefferyE commented on May 16, 2024 99
// 解法一:
for (let i = 0; i< 10; i++){
  setTimeout(() => {
    console.log(i);
  }, 1000)
}
// 解法二:
for (var i = 0; i< 10; i++){
  ((i) => {
    setTimeout(() => {
      console.log(i);
    }, 1000)
 })(i)
}

from daily-interview-question.

gaomin avatar gaomin commented on May 16, 2024 60
for (var i = 0; i< 10; i++){
  setTimeout(((i) => {
	console.log(i);
    })(i), 1000)
}

for (var i = 0; i< 10; i++){
   setTimeout((() => {
	console.log(i);
    })(), 1000)
}


for (let i = 0; i< 10; i++){
    setTimeout(() => {
	console.log(i);
    }, 1000)
}

from daily-interview-question.

MarsGT avatar MarsGT commented on May 16, 2024 59

正常写法:

for (var i = 0; i < 10; i++) {
    setTimeout(((i) => {
        console.log(i);
    })(i), 1000)
}

砸场子写法:

let i = 0,
timer = setInterval(() => {
    i < 10 ?
    console.log(i++) :
    clearInterval(timer);
})

from daily-interview-question.

btea avatar btea commented on May 16, 2024 35

利用try/catch的块级作用域也能实现目的:

for(var i = 0; i < 10; i++){ 
  try{
     throw i;
  }catch(i){
     setTimeout(() => { console.log(i); },1000)    
  }
}       

from daily-interview-question.

asd8855 avatar asd8855 commented on May 16, 2024 15

for (var i = 0; i < 10; i++) { console.log(i) }

from daily-interview-question.

jerrychane avatar jerrychane commented on May 16, 2024 14

闭包解法

setTimeout(() => {
	for (var i = 0; i< 10; i++){
	console.log(i);}
    }, 1000);

from daily-interview-question.

 avatar commented on May 16, 2024 14

其实有些方法是不满足要求的,为啥这样说呢?因为题目其实是有隐性要求,也即每隔 1s 输出一个数字,虽说题目没有明确说出来。所以这种解法不满足要求,比如:

for (var i = 0; i < 10; i++) {
  setTimeout(console.log(i, Date.now()), 1000)
}

from daily-interview-question.

lwmxiaobei avatar lwmxiaobei commented on May 16, 2024 8

for (let i = 0; i< 10; i++){
console.log(i);
}

又没说一定要用setTimeOut,这难道不是最简单效率最高的一种解法?

from daily-interview-question.

1921622004 avatar 1921622004 commented on May 16, 2024 7

压根就不需要改

from daily-interview-question.

Timi-code avatar Timi-code commented on May 16, 2024 7

看了很多,我再加一个吧

for (var i = 0; i < 10; i++) {
  console.log(i)
}

from daily-interview-question.

chphaeton avatar chphaeton commented on May 16, 2024 5

for (var i = 0; i< 10; i++){
console.log(i);
}
没有人这么写吗?不要打我啊

from daily-interview-question.

yuejuanmyword avatar yuejuanmyword commented on May 16, 2024 3
 for(let i = 0 ; i < 10; i++){
            setTimeout(()=>{
                console.log(i)
            },1000)
        }
for(var i = 0 ; i < 10 ; i++){
          (function(i){
              setTimeout(()=>{
                  console.log(i)
              },1000)
          }(i))
      }    

from daily-interview-question.

liyixun avatar liyixun commented on May 16, 2024 3
// 解法1 利用setTimeout的第三个参数
 for (var i = 0; i < 10; i++) {
    setTimeout( function timer(param){
        console.log(param);
    },1000, i);
}

// 解法2 用立即执行函数和闭包构建一个单独作用域
for (var i = 0; i < 10; i++) {
    (function(i){
      setTimeout( function (){
        console.log(i);
      },1000);
    })(i);
}

// 解法3 利用let构造块级作用域
for (let i = 0; i < 10; i++) {
    setTimeout( function (){
        console.log(i);
    },1000);
}

// 解法4 利用promise包装setTimeout
for (var i = 0; i < 10; i++) {
    timeoutPromise(i);
}
function timeoutPromise(i) {
    return new Promise((resolve) => {
        setTimeout(() => {
            console.log(i);
            resolve(true);
        }, 1000);
    });
}

// 解法5 用generator函数
for (var i = 0; i < 10; i++) {
    timeoutGenerator(i).next();
}
function* timeoutGenerator (i) {
    yield setTimeout(() => {
        console.log(i);
    }, 1000);
}

// 解法6 await async
async function init () {
    for (var i = 0; i < 10; i++) {
        await timeoutPromise(i);
    }    
}
function timeoutPromise (i) {
    return new Promise((resolve) => {
        setTimeout(() => {
            console.log(i);
            resolve(true);
        }, 1000);   
    });
}
init();

// 原题
for (var i = 0; i < 10; i++) {
    setTimeout( function (){
        console.log(i);
    },1000);
}

from daily-interview-question.

oliyg avatar oliyg commented on May 16, 2024 2
for (var i = 0; i< 10; i++){
   setTimeout((i) => {
   console.log(i);
   }, 1000,i)
}

除了 let 这个可能是改动最少的😂

from daily-interview-question.

oliyg avatar oliyg commented on May 16, 2024 1
for (var i = 0; i< 10; i++){
    (() => {
        var temp = i // 闭包
        setTimeout(() => {
            console.log(temp);
        }, 1000)
    })()
}

from daily-interview-question.

goodjs111 avatar goodjs111 commented on May 16, 2024 1

console.log(0),console.log(1),console.log(2),console.log(3),console.log(4),console.log(5),console.log(6),console.log(7),console.log(8),console.log(9)

from daily-interview-question.

zbyecho avatar zbyecho commented on May 16, 2024 1
  1. 解法1 将var 改为 let
{
    for (let i = 0; i< 10; i++){
        setTimeout(() => {
            console.log(i);
        }, 1000)
    }
}
  1. 解法二 利用 setTimeout 第三个参数
{
    for (var i = 0; i< 10; i++){
        setTimeout((j) => {
            console.log(j);
        }, 1000, i)
    }
}
  1. 解法三 利用闭包
{
    for (var i = 0; i< 10; i++){
        (
            function (j) {
                setTimeout(() => {
                    console.log(j);
                }, 1000);
            }
        )(i)
        
    }
}

from daily-interview-question.

MrLeihe avatar MrLeihe commented on May 16, 2024 1
// 1、let
for (let i = 0; i < 10; i++) {
  setTimeout(() => {
    console.log(i)
  }, 1000)
}

// 2、setTimeout 的第三个参数
for (var i = 0; i < 10; i++) {
  setTimeout(
    (a) => {
      console.log(a)
    },
    1000,
    i
  )
}

// 3、IIFE
for (var i = 0; i < 10; i++) {
  ;(function (a) {
    setTimeout(() => {
      console.log(a)
    }, 1000)
  })(i)
}

// 4、try catch 块级作用域
for (var i = 0; i < 10; i++) {
  try {
    throw i
  } catch (e) {
    setTimeout(() => {
      console.log(e)
    }, 1000)
  }
}

// 5、bind
for (var i = 0; i < 10; i++) {
    setTimeout(((i) => {
      console.log(i)
    }).bind(null, i), 1000)
}

from daily-interview-question.

Ljiaji avatar Ljiaji commented on May 16, 2024 1

兄弟们,给你们来个邪门歪道
for (var i = 0; i< 10; i++){
setTimeout(() => {
console.log(0-(i--)+10);
}, 1000)
}

from daily-interview-question.

gaomin avatar gaomin commented on May 16, 2024

利用try/catch的块级作用域也能实现目的:

for(var i = 0; i < 10; i++){ 
  try{
     throw i;
  }catch(i){
     setTimeout(() => { console.log(i); },1000)    
  }
}       

涨知识啦

from daily-interview-question.

SDXYRR avatar SDXYRR commented on May 16, 2024

for(let i=0;i<10;i++){
setTimeout(() => {
console.log(i);
}, 1000);
}

for(var i=0;i<10;i++){
(
function(){
var j = i;
setTimeout((()=>{
console.log(j)
}),1000)
}
)()
}

for(var i=0;i<10;i++){
(function(i){
setTimeout((()=>{
console.log(i)
}),1000)
})(i)
}

from daily-interview-question.

GitHdu avatar GitHdu commented on May 16, 2024
for (var i = 0; i< 10; i++){
   setTimeout(((i) => {
   console.log(i);
   }).call(null,i), 1000)
}

from daily-interview-question.

chenchangyuan avatar chenchangyuan commented on May 16, 2024

最简单的将var改成let

for (let i = 0; i< 10; i++){
   setTimeout(() => {
   console.log(i);
   }, 1000)
}

from daily-interview-question.

hmmoshang avatar hmmoshang commented on May 16, 2024

for (let i = 0; i< 10; i++){
setTimeout(() => {
console.log(i);
}, 1000)
}
for (var i = 0; i< 10; i++){
(function(i){
setTimeout(() => {
console.log(i);
}, 1000)
})(i)
}

from daily-interview-question.

Caitingwei avatar Caitingwei commented on May 16, 2024
  // 1 使用es5 块级作用域 let
  for (let i = 0; i< 10; i++){
    setTimeout(() => {
      console.log(i);
    }, 1000)
  }

  // 2 闭包法
  for (var i = 0; i< 10; i++){
    (function(i) {
      setTimeout(() => {
        console.log(i);
      }, 1000)
    })(i)
  }


  // 3 promise
  for (var i = 0; i< 10; i++){
    new Promise((r,ej) => ej(i)).catch(i => setTimeout(() => {
          console.log(i);
      }, 1000))
  }


  // 4 let 临时变量
  for (var i = 0; i< 10; i++){
    let _i = i;
    setTimeout(() => {
      console.log(_i);
    }, 1000)
  }

  // 5 setTimeout传参
  for (var i = 0; i< 10; i++){
    setTimeout(i => {
      console.log(i);
    }, 1000, i)
  }

  // 6 try catch法
  for (var i = 0; i< 10; i++){
    try {
      throw i;
    } catch (i) {
      setTimeout(() => {
        console.log(i);
      }, 1000)
    }
  }

from daily-interview-question.

thinkfish avatar thinkfish commented on May 16, 2024

for(var i = 0; i < 10; i++){
(function(){
console.log(i)
})()
}

from daily-interview-question.

Hunterang avatar Hunterang commented on May 16, 2024

1、闭包实现 变量保存,settimeout第三个参数转为函数参数也属于闭包。
2、let创建作用域,实现类似闭包的效果,变量保存
总结,学好闭包就可以了,作用域解决一切花里胡哨

from daily-interview-question.

chenming142 avatar chenming142 commented on May 16, 2024
for (var i = 0; i< 10; i++){
   setTimeout((i) => {
   console.log(i);
   }, 1000,i)
}

除了 let 这个可能是改动最少的

这两种解法,都好牛B

from daily-interview-question.

zhoushoujian avatar zhoushoujian commented on May 16, 2024

看到最后没有看到有人写一秒输出一个的情况。
一秒输出一个数字只需要在定时器后面乘以i即可,
setTimeout第一个参数是立即执行的函数除外。

from daily-interview-question.

mongonice avatar mongonice commented on May 16, 2024

方法1:立即执行函数表达式法简称(IIFE)不标准叫法立即执行函数

for (var i = 0; i<10; i++) {
     // IIFE: (function (j) {})(i);  
     (function (j) {
         setTimeout(function () {
            console.log(j)
         }, 1000)
      })(i)
}

方法2:将var 改为 let

for (let i = 0; i<10; i++) {
    setTimeout(function () {
         console.log(i)
    }, 1000)
}

方法3:使用promise函数

for (var i = 0; i<10; i++) {
   new Promise(function (resolve, reject) {
         resolve(i)
   }).then(function (data) {
        setTimeout(() => {
           console.log(data)
      }, 1000)
  })
}

方法4:使用bind绑定(参考楼上的,加深印象)

for(var i = 0; i<10; i++) {
     setTimeout(console.log.bind(null, i), 1000)
}

方法5: 使用try catch构成块级作用域(参考楼上的,加深印象)

for (var i = 0; i<10; i++) {
    try{
        throw(i)
    }catch (i) {
       setTimeout(function () { 
          console.log(i)
        },1000)
    }
}

另附promise相关的题目

from daily-interview-question.

HuangYongXuan avatar HuangYongXuan commented on May 16, 2024
    for (var i = 0; i< 10; i++){
        setTimeout((i) => {
            console.log(i);
        }, 1000, i)
    }

from daily-interview-question.

cheny-github avatar cheny-github commented on May 16, 2024

利用const/let的块级作用域

for (var i = 0; i< 10; i++){
    {
        const j=i;
        setTimeout(() => {
            console.log(j);
        }, 1000)
    }
}

下面这个比较奇葩,看到大佬的cath语句块延长作用域链,就想到了with。

for (var i = 0; i< 10; i++){
    with(new Number(i)){
        setTimeout(() => {
            console.log(valueOf());
        }, 1000)
    }
}

from daily-interview-question.

GrootWanggg avatar GrootWanggg commented on May 16, 2024

压根就不需要改

不改i一直++,打印出10.。。你自己试试

from daily-interview-question.

XJawher avatar XJawher commented on May 16, 2024
// 闭包
for (var i = 0; i < 10; i++) {
	(function (i){
		setTimeout(() => {
			console.log(i);
		}, 1000);
	})(i);
}

// 块作用域
for (let i = 0; i < 10; i++) {
	setTimeout(() => {
		console.log(i);
	}, 1000);
}

// timeout 传参
for (var i = 0; i < 10; i++) {
	setTimeout((i) => {
		console.log(i);
	}, 1000, i);
}

from daily-interview-question.

aoyeshirenbianchou avatar aoyeshirenbianchou commented on May 16, 2024

题目的意思应该是打印出0-9,并且使每隔1S打印出一个吧。不然setTimeout的意义在哪。直接for(var i=0;i<10;i++)(console.log(i))好了。所以每一个方法上都应该把定时器的时间 *i 吧

解决办法汇总

  • 方法一
    原理:

    • 利用 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)
    }
  • 方法二
    原理:

    • 利用 let 变量的特性 — 在每一次 for 循环的过程中,let 声明的变量会在当前的块级作用域里面(for 循环的 body 体,也即两个花括号之间的内容区域)创建一个文法环境(Lexical Environment),该环境里面包括了当前 for 循环过程中的 i具体链接

    代码 1:

    for (let i = 0; i < 10; i++) {
      setTimeout(() => {
        console.log(i);
      }, 1000)
    }

    等价于

    for (let i = 0; i < 10; i++) {
      let _i = i;// const _i = i;
      setTimeout(() => {
        console.log(_i);
      }, 1000)
    }
  • 方法三
    原理:

    代码 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)
      }
    }
  • 方法四
    原理:

    • 很多其它的方案只是把 console.log(i) 放到一个函数里面,因为 setTimeout 函数的第一个参数只接受函数以及字符串,如果是 js 语句的话,js 引擎应该会自动在该语句外面包裹一层函数

    代码 1:

    for (var i = 0; i < 10; i++) {
      setTimeout(console.log(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)
    }
  • 方法五
    原理:

    • 利用 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)
    }

from daily-interview-question.

lanOrage avatar lanOrage commented on May 16, 2024

解决办法汇总

  • 方法一
    原理:

    • 利用 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)
    }
  • 方法二
    原理:

    • 利用 let 变量的特性 — 在每一次 for 循环的过程中,let 声明的变量会在当前的块级作用域里面(for 循环的 body 体,也即两个花括号之间的内容区域)创建一个文法环境(Lexical Environment),该环境里面包括了当前 for 循环过程中的 i具体链接

    代码 1:

    for (let i = 0; i < 10; i++) {
      setTimeout(() => {
        console.log(i);
      }, 1000)
    }

    等价于

    for (let i = 0; i < 10; i++) {
      let _i = i;// const _i = i;
      setTimeout(() => {
        console.log(_i);
      }, 1000)
    }
  • 方法三
    原理:

    代码 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)
      }
    }
  • 方法四
    原理:

    • 很多其它的方案只是把 console.log(i) 放到一个函数里面,因为 setTimeout 函数的第一个参数只接受函数以及字符串,如果是 js 语句的话,js 引擎应该会自动在该语句外面包裹一层函数

    代码 1:

    for (var i = 0; i < 10; i++) {
      setTimeout(console.log(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)
    }
  • 方法五
    原理:

    • 利用 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)
    }

经过测试,我这边直接在settimeout里的第一个参数修改成js语句会报错:
0
timers.js:118
throw new ERR_INVALID_CALLBACK(callback);
^

TypeError [ERR_INVALID_CALLBACK]: Callback must be a function. Received undefined
at setTimeout (timers.js:118:11)

from daily-interview-question.

onionRunning avatar onionRunning commented on May 16, 2024
function* delay(i){
  yield setTimeout(() => {
    console.log(i)
  },1000*i)
} 
for (var j =0 ; j< 10; j++){
  delay(j).next()
}

from daily-interview-question.

yygmind avatar yygmind commented on May 16, 2024
for (var i = 0; i< 10; i++) {
  setTimeout(() => {
    console.log(i);
  }, 1000)
}

from daily-interview-question.

LiZhaoYangClub avatar LiZhaoYangClub commented on May 16, 2024
for (var i = 0; i< 10; i++){
	setTimeout((i) => {
		console.log(i);
    }, 1000,i)
}
for (var i = 0; i< 10; i++){
    ((i) => {
        setTimeout(() => {
            console.log(i);
        }, 1000)
    })(i)
}

from daily-interview-question.

thinkguo avatar thinkguo commented on May 16, 2024

for (let i = 0; i< 10; i++){ setTimeout(() => { console.log(i); }, 1000) }

from daily-interview-question.

UnrealCherry avatar UnrealCherry commented on May 16, 2024

大智若愚
for (var i = 0; i < 10; i++) {
console.log(i)
}

from daily-interview-question.

Wluyao avatar Wluyao commented on May 16, 2024

方式一

for (let i = 0; i < 10; i++) {
  setTimeout(() => {
    console.log(i);
  }, 1000 * i);
}

方式二

for (var i = 0; i < 10; i++) {
  (function (j) {
    setTimeout(() => {
      console.log(j);
    }, 1000 * j);
  })(i);
}

方式三

for (let i = 0; i < 10; i++) {
  setTimeout((i) => {
    console.log(i);
  }, 1000 * i, i);
}

方式四

let i = 0;
const timer = setInterval(() => {
  console.log(i);
  i++;
  if (i > 9) {
    clearInterval(timer);
  }
}, 1000);

from daily-interview-question.

cutie6 avatar cutie6 commented on May 16, 2024

解决办法汇总

  • 方法一
    原理:

    • 利用 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)
    }
  • 方法二
    原理:

    • 利用 let 变量的特性 — 在每一次 for 循环的过程中,let 声明的变量会在当前的块级作用域里面(for 循环的 body 体,也即两个花括号之间的内容区域)创建一个文法环境(Lexical Environment),该环境里面包括了当前 for 循环过程中的 i具体链接

    代码 1:

    for (let i = 0; i < 10; i++) {
      setTimeout(() => {
        console.log(i);
      }, 1000)
    }

    等价于

    for (let i = 0; i < 10; i++) {
      let _i = i;// const _i = i;
      setTimeout(() => {
        console.log(_i);
      }, 1000)
    }
  • 方法三
    原理:

    代码 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)
      }
    }
  • 方法四
    原理:

    • 很多其它的方案只是把 console.log(i) 放到一个函数里面,因为 setTimeout 函数的第一个参数只接受函数以及字符串,如果是 js 语句的话,js 引擎应该会自动在该语句外面包裹一层函数

    代码 1:

    for (var i = 0; i < 10; i++) {
      setTimeout(console.log(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)
    }
  • 方法五
    原理:

    • 利用 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)
    }

感觉就是两种方法:

  1. 将变化的数值的每一个瞬间当参数传入函数
  2. 块级作用域

from daily-interview-question.

wxthahha avatar wxthahha commented on May 16, 2024
    ### 第一种 var -> let
    ### 第二种 settimeout绑定参数,回调传参
    setTimeout((i) => {
      console.log(i);
    }, 1000,i)
    ### 第三种 使用外部变量保存每一次的i
    let j = i;
    setTimeout(() => {
      console.log(j);
    }, 1000)
   ###  第四种立即执行函数传参i或者回调函数包裹立即执行函数
    ((i)=>setTimeout(() => {
      console.log(i);
    }, 1000))(i)
    setTimeout(((i) => {
      console.log(i);
    })(i), 1000)
    ### 第五种bind或者call或者apply 也是为了传参 把每一次的i绑定
    setTimeout(((i) => {
      console.log(i);
    }).call({},i), 1000)

from daily-interview-question.

SnailOwO avatar SnailOwO commented on May 16, 2024
// let 块级作用域
 for (let i = 0; i < 10; i++) {
        setTimeout(() => {
            console.log(i);
        }, 1000)
    }

// 闭包
 for (var i = 0; i < 10; i++) {
        ((j) => {
            setTimeout(() => {
                console.log(j);
            }, 1000)
        })(i)
    }

// promise 异步,其实也可以用generator将i保存在堆中
 for (var i = 0; i < 10; i++) {
        new Promise((resolved, rejected) => {
            resolved(i);
        }).then((j) => {
            setTimeout(() => {
                console.log(j);
            }, 1000)
        })
    }

// try catch
for (var i = 0; i < 10; i++) {
        try {
            throw (i);
        } catch (i) {
            setTimeout(() => {
                console.log(i);
            }, 1000)
        }
    }

from daily-interview-question.

jackchang2015 avatar jackchang2015 commented on May 16, 2024
//来一个没提到的
function go(i){
    setTimeout(()=>{
        console.log(i)
    }, 1000*i)
}
for(var i = 0; i < 10; i++){
    go(i);
}

from daily-interview-question.

sharp08 avatar sharp08 commented on May 16, 2024

console.log(...[0,1,2,3,4,5,6,7,8,9])

from daily-interview-question.

zengkaiz avatar zengkaiz commented on May 16, 2024

// 方法1

for (var i = 0; i< 10; i++){
  (function fn(i){
    setTimeout(() => {
      console.log(i);
      }, 1000)
  })(i)
}

// 方法2

for (var i = 0; i< 10; i++){
  let y = i
  setTimeout(() => {
    console.log(y);
  }, 1000)
}

// 方法3

for (let i = 0; i< 10; i++){
  setTimeout(() => {
    console.log(i);
  }, 1000)
}

from daily-interview-question.

zengkaiz avatar zengkaiz commented on May 16, 2024

console.log(...[0,1,2,3,4,5,6,7,8,9])

are you dou 我?

from daily-interview-question.

CarberryChai avatar CarberryChai commented on May 16, 2024
for (var i = 0; i< 10; i++){
   setTimeout(console.log, 1000, i)
}

这是最简单的!

from daily-interview-question.

promotion-xu avatar promotion-xu commented on May 16, 2024
// 1. 通过立即执行函数,保存每一次遍历的i
// 相当于生成了 10个立即执行函数
for (var i = 0; i < 10; i++) {
  (function (i) {
    setTimeout(() => {
      console.log(i);
    }, 0);
  })(i);
}

// 2. 使用let 生成 块级作用域
for (let i = 0; i < 10; i++) {
  setTimeout(() => {
    console.log(i);
  }, 0);
}

from daily-interview-question.

webXLing avatar webXLing commented on May 16, 2024

// 创建函数 通过函数的入参生成新的变量-----

 for (var i = 0; i < 10; i++) {
    function name(i) {
      setTimeout(() => {
        console.log(i)
      }, 1000)
    }
    name(i)
  }

为啥没人写这个 而且 闭包能 解决这道题的原因该是因为函数的入参 生成的变量保留了i 而不是闭包的问题

from daily-interview-question.

Michael18811380328 avatar Michael18811380328 commented on May 16, 2024

我用 es6 实现一下

function sleep (time) {
  return new Promise((resolve) => setTimeout(resolve, time));
}

async function fn() {
  for (var i = 0; i < 10; i++){ 
    await sleep(1000);
    console.log(i);
  }
}

fn();

from daily-interview-question.

chris1299 avatar chris1299 commented on May 16, 2024
for (var i = 0; i < 10; i++) {  
    Promise.resolve(i).then((i)=>{
        setTimeout(() => {
            console.log(i)
        }, 1000);
    })
}

from daily-interview-question.

eavan5 avatar eavan5 commented on May 16, 2024

for (var i = 0; i < 5; i++) {
setTimeout(function (i) {
console.log(i);
}.bind(undefined, i), 1000);
}

from daily-interview-question.

caizihua avatar caizihua commented on May 16, 2024
for (var i = 0; i < 10; i++) {
  (function () {
    var j = i;
    setTimeout(() => {
      console.log(j);
    }, 0);
  })();
}

from daily-interview-question.

zhuziyi1989 avatar zhuziyi1989 commented on May 16, 2024
  1. JavaScript引擎执行机制?
  2. 放入异步任务队列的时机很重要!
  3. 理解作用域
  4. let在 for 循环的作用域在花括号内
  5. 闭包或箭头函数,他们在干什么?
	for (var i = 0; i < 10; i++) {
		(function(j){//闭包
			setTimeout(function(){
				console.log(j);//分别输出i的值
			},1000*j)	//设置明显的时间差
		})(i);//闭包
	};

理解到考点,背解意义不大。

from daily-interview-question.

gogopaner avatar gogopaner commented on May 16, 2024

for (var i = 0; i < 10; i++) { ( function(i) { setTimeout(() => { console.log(i); }, 1000) } )(i); };
for (var i = 0; i < 10; i++) { setTimeout((i) => { console.log(i); }, 1000,i) };

from daily-interview-question.

xiaohan-123 avatar xiaohan-123 commented on May 16, 2024

image

from daily-interview-question.

yaoocheng avatar yaoocheng commented on May 16, 2024

优秀,第三个参数可否解释下

from daily-interview-question.

xinxin-l avatar xinxin-l commented on May 16, 2024
//方法一
for (let i = 0; i < 10; i++) {
  setTimeout(() => {
    console.log(i)
  }, 1000)
}
//方法二
for (var i = 0; i < 10; i++) {
  (function(j) {
    setTimeout(() => {
      console.log(j)
    }, 1000)
  })(i)
}
//方法三
for (var i = 0; i < 10; i++) {
  foo(i)
}

function foo(i) {
  setTimeout(() => {
    console.log(i)
  }, 1000)
}
//方法四
for (var i = 0; i < 10; i++) {
  setTimeout((j) => {
    console.log(j)
  }, 1000, i)
}
//方法五
for (var i = 0; i < 10; i++) {
  new Promise(function(resolve, reject) {
    resolve(i)
  }).then(function(i) {
    setTimeout(() => {
      console.log(i)
    }, 1000)
  })
}

from daily-interview-question.

Yuweiai avatar Yuweiai commented on May 16, 2024

都不运行一下的吗

from daily-interview-question.

DaphnisLi avatar DaphnisLi commented on May 16, 2024

正常写法:

for (var i = 0; i < 10; i++) {
    setTimeout(((i) => {
        console.log(i);
    })(i), 1000)
}

砸场子写法:

let i = 0,
timer = setInterval(() => {
    i < 10 ?
    console.log(i++) :
    clearInterval(timer);
})

牛逼

from daily-interview-question.

qifengla avatar qifengla commented on May 16, 2024

在原始代码中,由于 setTimeout 回调函数是在循环结束后才执行,所以无论循环多快,输出的结果都会是 10 个 10。为了实现按顺序输出 0 - 9,可以尝试以下几种解法:

解法一:使用 let 关键字声明循环变量
for (let i = 0; i < 10; i++) {
setTimeout(() => {
console.log(i);
}, 1000);
}

解法二:使用闭包保存变量
for (var i = 0; i < 10; i++) {
(function (j) {
setTimeout(() => {
console.log(j);
}, 1000);
})(i);
}

解法三:使用 setTimeout 的第三个参数传递当前循环的索引
for (var i = 0; i < 10; i++) {
setTimeout((j) => {
console.log(j);
}, 1000, i);
}

解法四:使用 async/await 和 Promise
function delayLog(i) {
return new Promise((resolve) => {
setTimeout(() => {
console.log(i);
resolve();
}, 1000);
});
}

async function printNumbers() {
for (var i = 0; i < 10; i++) {
await delayLog(i);
}
}

printNumbers();

from daily-interview-question.

sunchengfeng01 avatar sunchengfeng01 commented on May 16, 2024

解法一

 for (let i = 0; i < 10; i++) `{`
 `console.log(i)`
}

解法二

   for (var i = 0; i < 10; i++) {
    setTimeout((a) => {
     console.log(a)
     }, 1000,i)
   }

解法三

for (var i = 0; i < 10; i++) {
  new Promise((resolve) => {
    resolve(i)
  }).then((res) => {
      setTimeout(() => {
        console.log(res)
      }, 1000)
  })
}

from daily-interview-question.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.