• 一道容易栽坑的有趣的面试题(关于js,定时器,闭包等)


    1.首先下面代码输出什么?

    1 for (var i = 0; i < 5; i++) {
    2   console.log(i);
    3 }

    输出:0 1 2 3 4

    2.上面只是普通的输出,没有陷阱再看下面这个题(套路开始了)

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

    输出:5 5 5 5 5 

    setTimeout 会延迟执行,那么执行到 console.log 的时候,其实 i 已经变成 5 了,因此会输出5个5

    3.上面的题超出我们的预想,我们肯定想得到的是0 1 2 3 4,那么问题来了 怎么才能输出0 1 2 3 4呢

    1 for (var i = 0; i < 5; i++) {
    2   (function(i) {
    3     setTimeout(function() {
    4       console.log(i);
    5     }, i * 1000);
    6   })(i);
    7 }

    或者:

    1 for(var i = 0; i < 5; i++) {
    2     setTimeout(function(i) {
    3         return function() {
    4             console.log(i);
    5         };
    6     }(i), i * 1000);
    7 }

    输出:0 1 2 3 4

    加上闭包,就能解决这个问题

    4.如第一个假设删除了function(i)中的i呢,怎么办?

    1 for (var i = 0; i < 5; i++) {
    2   (function() {
    3     setTimeout(function() {
    4       console.log(i);
    5     }, i * 1000);
    6   })(i);
    7 }

    输出:5 5 5 5 5 

    内部其实没有对 i 保持引用,其实会变成输出 5个5

    5.再更改一下

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

    输出:0 1 2 3 4 (立刻输出,没有时间间隔)

    给 setTimeout 传递了一个立即执行函数。setTimeout 可以接受函数或者字符串作为参数,那么这里立即执行函数是个啥呢,应该是个 undefined ,也就是说等价于:

    setTimeout(undefined, ...);

    而立即执行函数会立即执行,那么应该是立马输出的。

    “应该是立马输出 0 到 4 吧。”

    6.对于promise的考察

     1 setTimeout(function() {
     2   console.log(1)
     3 }, 0);
     4 new Promise(function executor(resolve) {
     5   console.log(2);
     6   for( var i=0 ; i<10000 ; i++ ) {
     7     i == 9999 && resolve();
     8   }
     9   console.log(3);
    10 }).then(function() {
    11   console.log(4);
    12 });
    13 console.log(5);

    输出:2 3 5 4 1

    考察 JavaScript 的运行机制的,

    首先先碰到一个 setTimeout,于是会先设置一个定时,在定时结束后将传递这个函数放到任务队列里面,因此开始肯定不会输出 1 。

    然后是一个 Promise,里面的函数是直接执行的,因此应该直接输出 2 3 。

    然后,Promise 的 then 应当会放到当前 tick 的最后,但是还是在当前 tick 中。

    因此,应当先输出 5,然后再输出 4 。

    最后在到下一个 tick,就是 1 。

    所以输出:2 3 5 4 1

  • 相关阅读:
    【分享】64K视频合集
    【原译】四种方法统计字符串的行数&执行时间比较
    【原译】自动省略功能的WPF文本框控件
    【笔记】MD5加密
    【原译】在amazon kindle上安装Metasploit
    【笔记】wubi安装ubuntu遇到的问题
    【笔记】贪心算法找零钱(C#实现)
    ubuntu下在java代码中调用c代码
    sql截取字段最后以特定字符隔开的内容语句
    mysql中删除字符串或字段中空格函数
  • 原文地址:https://www.cnblogs.com/zhangxue521/p/6710319.html
Copyright © 2020-2023  润新知