在掘金上看到了篇文章,里面讲了几个js代码片段,觉得很有意思,其中考察了关于setTimeout
、函数闭包
、IIFE(立即执行函数表达式)
、promise
、js解释器
等概念的理解
A:下面的程序输出啥?
for(var i=0;i<5;i++){ |
我:没有坑,别想多了。输出0 1 2 3 4
A:恩,那下面这个呢?
for(var i=0;i<5;i++){ |
我:settimeout
时间到后,会在下一个tick中执行程序,所以程序打印的时候,i已经变成5了,输出5 5 5 5 5
。
A:不错,那我想输出的结果是0 1 2 3 4
,应该怎么办呢?
我:用闭包就解决了,如下
for(var i=0;i<5;i++){ |
因为函数作用域内,保存着对于变量i的引用,故函数执行的时候仍能访问到当初的i。
A:很好。那如果去掉参数i呢?
for(var i=0;i<5;i++){ |
我:这样的话,函数闭包内没有存储对i保持引用,所以输出结果又会变成5 5 5 5 5
A: 对。那我再给你改一下程序,你看看输出啥?
//给setTimeout传递一个立即执行函数 |
我:这里给setTimeout
传递的是一个立即执行函数表达式,它会马上运行,执行结果是undefined
,所以setTimeout
输出0之后,应该会报错吧,因为参数传递不对,应该接受一个函数类型的参数。
上面的代码差不多等于:
//其实等价于 |
A:恩!再看下面的这个程序输出什么?
setTimeout(function() { |
我:思考半天…,应该输出2 3 5 4 1
。这个题目是关于js解释器理解的。setTimeout
中的函数会在下一个时钟周期运行,肯定比较靠后。2,3
在立即执行函数中,所以他会立马打印。4
在then
中输出,它会放在当前周期的最后执行。最后5
会立马打印。所以会这样2 3 5 4 1
。
疑问:关于setTimeout和promise.then执行先后的问题,上网找了一下原因,setTimeout属于Macrotask
,而promise属于Microtask
,Microtask
在当前周期队列执行,Macrotask
在下一周期执行。