💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
## js事件循环中的上下文和作用域的经典问题 你是否遇到过,for 中 setTimeout 变量总是最后一个的问题,以及在 for 中绑定事件 出问题的情况? https://blog.csdn.net/weixin_34194317/article/details/88860643 js有两个执行栈:主栈 和 EventLoop Stack(事件循环栈) ```javascript // 主栈从上往下执行 var a = 1; // 定义一个函数,注意它接受一个参数,返回值是一个函数 var f = function(a) { // 返回一个函数,或者说生成一个函数,并返回 return function () { console.log('___ ', a); // 根据作用域原型链规则,这里的 变量a 将指向 参数a } } // 和下面的唯一区别是,第一个参数是一个表达式,而不是一个函数体定义 // 这是一个函数立即执行表达式,且传递了一个参数a,此时变量a的值为 1 // 表达式的返回值是一个函数,这正是 setTimeout 所需要的 // 这里能“保住上下文变量a”的关键是,a:1 被 固化到生成的函数中去了 setTimeout(f(a), 200); // 主执行栈,创建一个 定时器事件 // 定时器到期时会将 事件 push 到 事件循环队列上去 setTimeout(function(){ console.log('__', a); // 根据作用域原型链规则,这里的 变量a 将指向 上面定义的全局变量a }, 100); a = 2; console.log('_', a); // 主栈执行完毕,开始进入 事件循环栈 ``` ~~~ // 输出: _ 2 __ 2 ___ 1 ~~~ 如果你理解上面的演示程序和输出结果,那么你就明白了这个经典问题。 ---- [理解 JavaScript 的 async/await_边城客栈 - SegmentFault 思否](https://segmentfault.com/a/1190000007535316) [大前端进击之路(二):JavaScript异步编程](https://mp.weixin.qq.com/s/JO9c0_emIXj_PlFEO4DX7Q) [js async/await - 码农1213 - 博客园](https://www.cnblogs.com/bear-blogs/p/10423759.html) [js中的宏任务与微任务_个人文章 - SegmentFault 思否](https://segmentfault.com/a/1190000020225668) > 所以它的响应速度相比setTimeout(setTimeout是task)会更快,因为无需等渲染。也就是说,在某一个macrotask执行完后,就会将在它执行期间产生的所有microtask都执行完毕(在渲染前)。 > > (微任务可以看作是一个列表,每次每次执行栈task执行后都会全部执行完,清空,并不是队列只取一个来进行执行),所以可以把微任务看作是紧急任务列表,每个任务执行后,都要马上处理它们。 > 同步任务直接进入执行栈,每次执行后都会处理执行全部微任务,执行栈空后才会进入事件循环获取一个任务放入执行栈执行。 > > 三个要点:执行栈(栈上的每个任务都是宏任务),微任务列表,任务队列 ---- [let 和 const 命令 - ECMAScript 6入门 - 阮一峰](https://es6.ruanyifeng.com/#docs/let#基本用法) ```javascript var a = []; for (var i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 10 var a = []; for (var i = 0; i < 10; i++) { var f = function (i) { // 返回 匿名函数 // 匿名函数中的 i 会指向 此实参数 i ,但是返回 匿名函数后, i 就会 和 上面的 i 脱钩 return function () { // i 被传入 匿名函数 暂存 console.log(i); } }; // 执行函数,将 i 传入 a[i] = f(i); } a[6](); // 6 var a = []; for (let i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 6 ``` ---- last update: 2020-11-02 12:20:11