const obj = {
name: " jsCoder",
skill: ["es6", "react", "angular"],
say: function ()
{
var that = this;
for (var i = 0, len = this.skill.length; i < len; i++)
{
setTimeout((function()
{
console.log(i);
console.log(that.skill[i]);
})(), 0)
console.log(i);
}
}
};
obj.say();
这段代码在Node里执行会报错,但可以在浏览器中执行,执行结果:
第二种写法:
const obj = {
name: " jsCoder",
skill: ["es6", "react", "angular"],
say: function () {
var that = this;
for (var i = 0, len = this.skill.length; i < len; i++) {
(function () {
var j = i;
setTimeout((function () {
console.log(j);
console.log(that.skill[j]);
}), 0)
})()
console.log(i);
}
}
};
obj.say();
为什么,立即执行函数是异步任务吗?
首先setTimeout是异步执行的,堆栈中碰到setTimeout会交给浏览器内核处理,等待setTimeout达到触发条件(即设定的时间),再返回给执行队列.先说说概念
第一种情况setTimeout里的function用立即执行函数,会直接执行。如果你把后面的()去掉你便会发现不会立即执行,而且后面输出的为undefine因为已经被回收啦
第二种情况setTimeout外加入了闭包,闭包中的变量会保存在内存中,并不会被垃圾回收机制回收。所以闭包中的i赋值给j后,j一直都存在,并未被回收,前面的0,1,2是主线程的i,后面的0,es6,1,react,2,angular则是setTimeout里输出的。立即函数不是异步的,setTimeout才是,交给浏览器内核处理再返回给执行队列的是setTimeout