1.let在for循环头部时的特殊行为
首先看第一张图:
从词法作用域的角度看,异步操作中找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