JS小知识点汇总

950 阅读2分钟

1.let在for循环头部时的特殊行为

2d560c2e0ea49c95f4b2d30e29b42bb.png

1635239184(1).png

首先看第一张图:

从词法作用域的角度看,异步操作中找this.a也是在定义的地方去找,然后结果一直是2(此时同步操作已执行完毕)。

在for循环中,每一轮的变量i都是重新声明的新变量,实际上()是{}的父级代码块,而本例中有三个({})这样的代码块,每个代码块中的i都是新定义的变量i(从let i = xxx 这个语法就能看出来),js引擎每次都会记录上一次循环的值,然后赋值给本轮的新变量i。所以打印i的时候,它都找到了自己的代码块,所对应的i值。

再看第二张图:

这里验证了刚才的说法,在{}代码块中重新定义let i,不会影响父级代码块()中的循环,打印三次。但是如果直接操作i,更改了父级里面的i,js引擎记录了错误的值,导致判断条件不成立,便退出了循环。

2.setTimeout

在chrome中(实际很多浏览器都沿用了这一规则),setTimeout最小延时是1ms。

setTimeout(function() {
    console.log('嘤嘤嘤1');
}, 1);
setTimeout(function() {
    console.log('嘤嘤嘤2');
}, 0);
// 按这个理论应该是嘤嘤嘤1、嘤嘤嘤2.
// 但是chrome实际操作打印还是嘤嘤嘤2、嘤嘤嘤1,说明强大的chrome已经优化了,然后又做了个有趣的实验,发现零点几都比1快,和0一样快,零点几之前没区别。基本可以得出结论,最新的chrome是把零点几统一当0处理了,而0现在确实比1快。

setTimeout嵌套超过5层,延时最少是4毫秒。(4ms是性能上的考虑,为了避免bug,优秀的chrome团队首先实践得出的数值,后被用作规范)

setTimeout(function() {
     console.log('嘤嘤嘤1');
    setTimeout(function() {
        console.log('嘤嘤嘤2');
        setTimeout(function() {
            console.log('嘤嘤嘤3');
            setTimeout(function() {
                    console.log('嘤嘤嘤4');
                setTimeout(function() {
                        console.log('嘤嘤嘤5');
                }, 0);
            }, 0);
        }, 0);
    }, 0);
}, 0);

setTimeout(function() {
    console.log('嘤嘤嘤999');
}, 3);
// 嘤嘤嘤1 嘤嘤嘤2 嘤嘤嘤3 嘤嘤嘤4 嘤嘤嘤999 嘤嘤嘤5 说明第5个的延时是4
// 下面的延时从3改成1结果不变,说明前4个其实都是0