当前位置:网站首页>js中的作用域与作用域链
js中的作用域与作用域链
2022-04-23 05:56:00 【画不完的饼】
作用域与作用域链
首先先看一个例子:
let x = 1;
function A(y){
let x = 2;
function B(z){
console.log(x+y+z)
}
return B
}
let C = A(2);
C(3);
先来看以下,js底层代码执行的一个顺序:
ECstack = [ //执行栈
EC(G)={ //创建全局执行上下文
VO(G):{ //全局变量对象
... //包含全局对象原有的属性
x=1;
A=function(y){...} //创建函数的时候就确定了其作用域 (重点)
A[[scope]] = VO(G);
}
}
]
注:我们不管在哪一个执行上下文当中,除了创建变量或者堆以外,同时给当前的函数,声明了它所在的作用域是谁。
看上方例子,函数A在全局创建的,那么A的作用域就是全局的执行上下文。当A执行的时候,就会生成一个新的执行上下文(每个函数执行都会生成一个私有的执行上下文)。
此时,在A的执行上下文,我又创建了一个B函数。那么B也会生成一个私有的执行上下文,同时B的作用域也会被创建,那么B是在A的执行上下文创建的,那么B的函数作用域就是,当前这个A的执行上下文。
函数在执行上下文,除了获取arguments(实参对象),生成作用域外,还做了一件事,生成this指向
函数执行,有个执行主体,进来的第一件事情就是声明this指向,this指向后面说。
除此之外,它还初始化了它的链表,也就是我们常说的作用域链。作用域链的查找规则,就是上面加粗的文字。
下面总结一下:
函数的执行机制:
创建函数的时候:
(1)创建一个堆(存储代码字符串和对应的键值对)
(2)初始化了当前函数的作用域[[scope]]
作用域[[scope]]指的是所在上下文EC中的变量对象VO(变量对象)/AO(函数内的变量对象)
严格来说的话。作用域[[scope]] 与执行上下问是有区别的,作用域指的是当前上下问具体的存放变量的地方,上下文是既可以存变量,又能压缩代码放到执行栈执行的。但是,编程中,我们认为他们俩没啥区别,其实也是不会出错的。
函数执行的时候
创建一个新的执行上下文EC,并且压缩至栈(EC stack)里执行。
初始化this指向
初始化作用域链
创建AO变量对象存储变量
变量又会进行 arguments(它是函数运行时的实参对象) =》 形参 --》如果有变量提升,将变量提升,如果没有变量提升,会将代码执行。
下面看一下,上面题闭包的形成,以及作用域链的查找方式
重:
创建函数的时候,形成的是作用域,以及作用域是谁,函数执行的时候,一定会先初始化好它的作用域链,代码执行当中,遇到一个变量,首先看看它是不是私有变量,如果是,用自己的,如果不是,就会沿着作用域链,一级一级往上查找,一直查找到全局位置,找不到就会报错。这就是闭包,作用域链的一个查找过程。
版权声明
本文为[画不完的饼]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_39162041/article/details/105217720
边栏推荐
- 微信小程序之点击取消,返回上页,修改上页的参数值,let pages=getCurrentPages() let prevPage=pages[pages.length - 2] // 上一页的数据
- Detailed explanation and application principle of token
- excel快速自动填充空白单元格上一行的内容
- 手动实现简单的Promise及其基础功能
- 常用sql语句收藏
- sqlserver性能优化建议
- 2022ldu winter vacation training - program patch
- Use of shell scripts & and 𞓜
- 查漏补缺(一)
- Log writing method (with time)
猜你喜欢
随机推荐
ECMAScript历史
Modify registry values
ASP.NET CORE JWT认证
Log writing method (with time)
Vs can be compiled, but there will be a red underline to indicate the problem of undefined identifiers
JS高频面试题
邮箱字符串判断
微信小程序之 js 时间戳/1000 转换 秒,六个小时后,一天后,本周五 选项计算时间
Generate shortcut
JS实现私有属性
查漏补缺(六)
ES6面试题(参考文档)
uniapp 自定义搜索框适配小程序对齐胶囊
往String原型上封装一个时间戳转日期的方法
元编程,代理Proxy与反射Reflect
WebSocket(基础)
查漏补缺(七)
.Net Core 下使用 Quartz —— 【6】作业和触发器之触发器的日历
Informatics one book pass - small ball
ES6新增方法