Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

一道有趣的面试题(setTimeout in for loop) #94

Open
felix-cao opened this issue Oct 23, 2018 · 0 comments
Open

一道有趣的面试题(setTimeout in for loop) #94

felix-cao opened this issue Oct 23, 2018 · 0 comments

Comments

@felix-cao
Copy link
Owner

felix-cao commented Oct 23, 2018

Test1

for (var i = 0; i < 5; i++) {  // 注意是 i < 5, 不是 <= 5
    setTimeout(function(i) {
        console.log(i);
    }, 1000);
}
// 同时打出5个5

Test2, 现在把 setTimeout 的第二个参数改一下

for (var i = 1; i < 5; i++) {
  setTimeout(function() {
      console.log(i)
  }, i * 1000)
}
// 以一秒的频率连续输出五个5!

二、如何要它以一秒的频率分别输出 01234。

2.1、for 循环体为立即执行函数 IIFE

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

2.2、使用 ES6 中 let 关键词

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

for 循环头部的 let 声明还会有一个特殊的行为。这个行为指出变量在循环过程中不止被声明一次,每次迭代都会声明。随后的每个迭代都会使用上一个迭代结束时的值来初始化这个变量。

2.3、bind 绑定

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

2.4、使用 setTimeout 的第三个参数

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

2.5、把 setTimeout 用一个方法抽出来形成闭包

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

三、延伸

var test = function () {
  var arr = []
  for(var i = 0; i < 5; i++){
    arr.push(function () {
      return i*i
    })
  }
  return arr
}

var test1 = test()
console.log(test1[0]())
console.log(test1[1]())
console.log(test1[2]())

上面的代码在 test 函数返回一个函数数组 arr, 内部的for循环里,为 arr 数组 push 了5个函数,均为:

function () {
  return i*i
}

我们期望这里的 test1 函数数组中每个函数执行的时候,能够得到在循环时的 i 值,但是显然没能如我们所料。这是为什么呢?

@felix-cao felix-cao changed the title 一个有趣的面试题(for setTimeout) 一道有趣的面试题(for setTimeout) Oct 23, 2018
@felix-cao felix-cao changed the title 一道有趣的面试题(for setTimeout) 一道有趣的面试题(setTimeout in for loop) Oct 24, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant