## 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
- 开始
- 微信小程序
- 获取用户信息
- 记录
- HTML
- HTML5
- 文档根节点
- 你真的了解script标签吗?
- 文档结构
- 已经落后的技术
- form表单
- html实体
- CSS
- css优先级 & 设计模式
- 如何编写高效的 CSS 选择符
- 笔记
- 小计
- flex布局
- 细节体验
- Flex
- Grid
- tailwindcss
- JavaScript
- javascript物语
- js函数定义
- js中的数组对象
- js的json解析
- js中数组的操作
- js事件冒泡
- js中的判断
- js语句声明会提前
- cookie操作
- 关于javascript你要知道的
- 关于innerHTML的试验
- js引擎与GUI引擎是互斥的
- 如何安全的修改对象
- 当渲染引擎遇上强迫症
- 不要使用连相等
- 修改数组-对象
- 算法-函数
- 事件探析
- 事件循环
- js事件循环中的上下文和作用域的经典问题
- Promise
- 最佳实践
- 页面遮罩加载效果
- 网站静态文件之思考
- 图片加载问题
- 路由及转场解决方案
- web app
- 写一个页面路由转场的管理工具
- 谈编程
- 技术/思想的斗争
- 前端技术选型分析
- 我想放点html模板代码
- 开发自适应网页
- 后台前端项目的开发
- 网站PC版和移动版的模板方案
- 前后端分离
- 淘宝前后端分离
- 前后端分离的思考与实践(一)
- 前后端分离的思考与实践(二)
- 前后端分离的思考与实践(三)
- 前后端分离的思考与实践(四)
- 前后端分离的思考与实践(五)
- 前后端分离的思考与实践(六)
- 动画
- 开发小技巧
- Axios
- 屏幕适配
- 理论基础
- 思考
- flexible.js原理
- 实验
- rem的坑,为什么要设置成百分比,为什么又是62.5%
- 为什么以一个标准适配的,其它宽度也能同等适配
- 自适应、响应式、弹性布局、屏幕适配
- 适配:都用百分比?
- 番外篇
- 给你看看0.5px长什么样?
- 用事实证明viewport scale缩放不会改变rem元素的大小
- 为什么PC端页面缩放不会影响rem元素
- 究竟以哪个为设备独立像素
- PC到移动端初试
- 深入理解px
- 响应式之栅格系统
- 深入理解px(二)
- 一篇搞定移动端适配
- flex版栅格布局
- 其他
- 浏览器加载初探
- 警惕你的开发工具
- JS模块化
- webpack
- 打包原理
- 异步加载
- gulp
- 命名规范
- 接口开发
- sea.js学习
- require.js学习
- react学习
- react笔记
- vue学习
- vue3
- 工具、技巧
- 临时笔记
- 怎么维护好开源项目
- 待办
- 对前端MVV*C框架的思考
- jquery问题
- 临时
- 好文
- 节流防抖