作用域和堆栈内存

举报
小妖现世 发表于 2020/07/24 19:15:31 2020/07/24
【摘要】 今天来详细解释一下作用域和变量提升,因为最近的课程也讲到了,我认为有必要把这块在拓展一下基于let, const ,class, import等ES6中的等方式创建变量,不存在变量提升后期函数中代码执行,遇到一个变量,首先看是否为自己上下文中私有变量,如果以后操作的都是自己的私有变量,和外界无关;如果不是自己私有的,则按照作用域链,到上一级上下文EC(G)中查找,看看是否是它的...我们把变...

今天来详细解释一下作用域和变量提升,因为最近的课程也讲到了,我认为有必要把这块在拓展一下

基于let, const ,class, import等ES6中的等方式创建变量,不存在变量提升

后期函数中代码执行,遇到一个变量,首先看是否为自己上下文中私有变量,如果以后操作的都是自己的私有变量,和外界无关;如果不是自己私有的,则按照作用域链,到上一级上下文EC(G)中查找,看看是否是它的...我们把变量的这种查找机制,叫做“作用域链”,一直找到全局上下文位置

代码执行前的预处理:

1、初始化作用域链:scope-chain(EC(FN1), EC(G))

2、初始化this

3、形参赋值

5、变量提升

6、代码开始执行

一般函数执行,形成的上下文,在函数执行完都会出栈释放,以此保证内存优化,;如果当前上下文中的某些东西,被上下文之外的变量等占用了,则不能出栈释放,此上下文之前存储的私有变量也都保存下来了

作用域链和函数在哪执行没关系,上级作用域[[scope-chain]],只和在哪创建的有关系,创建时候就已经决定了未来作用域链的指向

在JS非严格模式下,arguments和形参变量存在映射机制(因为都是用来存储传递的实参信息的,arguments不管是否定义形参都会存在,定义形参后,不仅形参可以获取传递的值,arguments中也存储了传递的值,此时两者有映射机制)

    第一个形参变量 映射 arguments[0]

    第二个形参变量 映射  arguments[1]

    后期不论是形参变量更改值,还是arguments更改每一项的值,互相都会跟着改变

"use strict"; //使用JS严格模式,映射机制不存在,此处只是把arguments修改了,形参是不会跟着改变的

自执行函数的创建和执行发生在代码执行阶段

堆栈释放问题:

JS中的内存:堆内存(HEAP)和栈内存(STACK)

    堆内存是用来存储引用数据类型值的(例如:创建函数的创建对象,就是开辟一个堆内存,把代码字符串或者键值对存储到堆内存中)

    栈内存是用来执行代码和存储基本类型值的(创建变量也存在里面了),而且不仅全局代码执行(EC(G)全局执行上下文),而且函数执行(EC(X)私有上下文),最后也都会进栈执行的

x=y={xx:"xx"}

1、先创建堆

2、x={xx:"xx"}

3、y={xx:"xx"}

浏览器常用的垃圾回收机制(内存释放机制):

    查找引用(webkit内核):

        浏览器有自动回收垃圾的机制,定期间隔某段时间,把所有没有被占用的内存回收释放

        创建一个堆(16进制地址),如果有变量或者其他东西存储了堆内存地址,则当前堆内存被视为占用,也就不能释放销毁

        上下文进栈执行,如果当前上下文中的某些内容(一般也是当前上下文中创建的堆)被上下文以为的变量或者其他事务所占用,那么当前上下文就不能出栈释放(一般情况下,上下文中代码执行完,上下文自己就出栈释放了)

    内存计数器方式(Trident内核):

        当前内存被其他东西引用了,则给堆计数+1(累加计数),取消占用后,则-1,当减到零之后,浏览器就可以把它释放了

    

如果堆内存用完后,手动释放它,则取消所用的占用:赋值为null(null是空对象指针,也就是不指向任何的堆内存)


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。