美文网首页前端100问
【前端100问】Q31:改造下面的代码,使之输出 0 - 9,写

【前端100问】Q31:改造下面的代码,使之输出 0 - 9,写

作者: alanwhy | 来源:发表于2020-12-27 11:30 被阅读0次

    写在前面

    此系列来源于开源项目:前端 100 问:能搞懂 80%的请把简历给我
    为了备战 2021 春招
    每天一题,督促自己
    从多方面多角度总结答案,丰富知识
    改造下面的代码,使之输出 0 - 9,写出你能想到的所有解法。
    简书整合地址:前端 100 问

    题目

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

    正文回答

    方法一

    原理:

    • 利用 setTimeout 函数的第三个参数,会作为回调函数的第一个参数传入
    • 利用 bind 函数部分执行的特性
    // setTimeout(function, milliseconds, param1, param2, ...)
    // function 必需。要调用一个代码串,也可以是一个函数。
    // milliseconds 可选。执行或调用 code/function 需要等待的时间,以毫秒计。默认为 0。
    // 可选。 传给执行函数的其他参数(IE9 及其更早版本不支持该参数)。
    for (var i = 0; i < 10; i++) {
      setTimeout(
        (i) => {
          console.log(i);
        },
        1000,
        i
      );
    }
    
    for (var i = 0; i < 10; i++) {
      setTimeout(console.log, 1000, i);
    }
    
    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

    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);
    }
    
    方法三

    利用函数自执行的方式,把当前 for 循环过程中的 i 传递进去,构建出块级作用域。IIFE 其实并不属于闭包的范畴。

    利用其它方式构建出块级作用域

    for (var i = 0; i < 10; i++) {
      ((i) => {
        setTimeout(() => {
          console.log(i);
        }, 1000);
      })(i);
    }
    
    for (var i = 0; i < 10; i++) {
      try {
        throw new Error(i);
      } catch ({ message: i }) {
        setTimeout(() => {
          console.log(i);
        }, 1000);
      }
    }
    
    方法四

    利用 eval 或者 new Function 执行字符串

    for (var i = 0; i < 10; i++) {
      setTimeout(eval("console.log(i)"), 1000);
    }
    
    for (var i = 0; i < 10; i++) {
      setTimeout(new Function("i", "console.log(i)")(i), 1000);
    }
    
    for (var i = 0; i < 10; i++) {
      setTimeout(new Function("console.log(i)")(), 1000);
    }
    

    相关文章

      网友评论

        本文标题:【前端100问】Q31:改造下面的代码,使之输出 0 - 9,写

        本文链接:https://www.haomeiwen.com/subject/vdkonktx.html