—调用的时机不同,结果也就不同—

1.什么时候才是调用函数

  • 当给你一个函数的时候,这个函数并没有被调用 ,如下,最后一行的 fn() 才是调用函数

    1. let a = 1
    2. function fn(){
    3. console.log(a)
    4. }
    5. fn
    6. fn() //1

    2.普通的函数调用时机

  • 那么执行以下代码结果如何

    1. let a = 1
    2. function fn(){
    3. console.log(a)
    4. }
    5. a=2
    6. fn() //2

    以上代码如果 a=2 在 fn() 之后,那么打印出来的就是 1

    3.setTimeout() 调用时机

  • 使用 setTimeout() — 设置一个定时器,到时间执行函数或代码

  • 一般也说 马上/尽快/过一会儿 执行(把当前事件处理完,再执行里面的函数或代码)
  • setTimeout() 是一个异步任务

    3.1.for 循环里面加 setTimeout() 会出现什么结果呢

    1. let i = 0
    2. for(i = 0; i<6; i++){
    3. setTimeout(()=>{
    4. console.log(i)
    5. },0)
    6. }
    7. //6个6
  • [x] 在不加 setTimeout() 时,我们知道这是一个很普通的 for 循环,应该是打印出 0、1、2、3、4、5

  • [x] 而上面也说了 setTimeout() 里面的函数是过一会儿才执行,也就是每次执行 for 循环,setTimeout 都执行一次,但是里面的函数不执行,等到 for 循环执行完,此时 i=6,再去执行 setTimeout() 里的函数,所以是打印出6个6

    3.2.那么怎么样才能打印出 0、1、2、3、4、5 呢

  • [x] 第一种:let 声明放到 for 循环里面

    1. for(let i = 0; i<6; i++){
    2. setTimeout(()=>{
    3. console.log(i)
    4. },0)
    5. }
    6. //0、1、2、3、4、5

    每次循环都会多创建一个新的 i ,最后执行函数输出的是每一次循环里的 i

  • [x] 第二种:for 循环里再声明一个 x 使其 = i

    1. let i
    2. for(i = 0; i<6; i++){
    3. let x = i
    4. setTimeout(()=>{
    5. console.log(x)
    6. })
    7. }

    [x] 第三种:使用立即执行函数

    1. let i
    2. for(i = 0; i<6; i++){
    3. !function(x){
    4. setTimeout(()=>{
    5. console.log(x)
    6. },0)
    7. }(i)
    8. }
  • [x] 第四种:利用 setTimeout() 的附加参数(附加参数可以有多个,定时器到期会将参数传给 function)

    1. let i
    2. for(i = 0; i<6; i++){
    3. setTimeout((x)=>{
    4. console.log(x)
    5. },0,i)
    6. }