美文网首页
作用域和内存问题

作用域和内存问题

作者: A郑家庆 | 来源:发表于2019-01-23 12:15 被阅读0次

基本类型和引用类型

  6种基本数据类型:Undefined、Null、Boolean、Number、String、Symbol。基本数据类型是按值访问的,因为可以操作保存在变量中的实际的值。
  引用类型的值是保存在内存中的对象。当复制对象的时候操作的是对象的引用,但在为对象添加属性时,操作的是实际对象。引用类型的值是按引用访问的。

执行环境和作用域的区别

  作用域分为全局作用域和局部作用域,全局作用域是整个程序在运行时都能访问的;局部作用域中包含了函数作用域和块级作用域。
  每个函数都有自己的执行环境(execution context)。当执行流进入一个函数时,函数的环境就会被推入一个环境栈中。而在函数执行之后,栈将其环境弹出,把控制权返回给之前的执行环境。
  自我理解(未确认):JavaScript的代码在执行前会确定作用域,产生作用域链,然后当执行到某个函数的时候,函数执行环境就被推入环境栈,执行环境上就会添加变量对象、活动对象、作用域链这些东西。变量对象和活动对象是差不多的,只是状态不一样,一个是执行前确定的,一个是执行时用到的,上面保存了函数中定义的变量或者函数声明。作用域是一套规则,用来确定在何处以及如何查找对象,当作用域嵌套的时候,就产生了作用域链,当前作用域没有找到变量的时候,就在上一层作用域查找,直到找到变量或者到达最外层作用域。

执行环境及作用域链

  执行环境是JavaScript中最为重要的一个概念。执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为。每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象 中。虽然我们编写的代码无法访问这个对象,但解析器在处理数据时会在后台使用它。
  每个函数都有自己的执行环境。当执行流进入一个函数时,函数的环境就会被推入一个环境栈中。而在函数执行之后,栈将其环境弹出,把控制权返回给之前的执行环境。ECMAScript程序中的执行流正是由这个方便的机制控制着。
  当查找变量的时候,会先从当前上下文的变量对象中查找,如果没有找到,就会从父级(词法层面上的父级)执行上下文的变量对象中查找,一直找到全局上下文的变量对象,也就是全局对象。这样由多个执行上下文的变量对象构成的链表就叫做作用域链。
  当代码在一个环境中执行时,会创建变量对象的一个作用域链。作用域链的用途是保证对执行环境有权访问的所有变量和函数的有序访问。

垃圾收集

  JavaScript具有自动垃圾收集机制,也就是说,执行环境会负责管理代码执行过程中使用的内存。这种垃圾收集机制的原理其实很简单:找出那些不再继续使用的变量,然后释放其占用的内存。为此,垃圾收集器会按照固定的时间间隔周期性地执行这一操作。
  下面我们来分析一下函数中局部变量的正常生命周期。局部变量只在函数执行的过程中存在。而在这个过程中,会为局部变量在栈或堆内存上分配相应的空间,以便存储它们的值。然后在函数中使用这些变量,直至函数执行结束。此时,局部变量就没有存在的必要了,因此可以释放它们的内存以供将来使用。
  垃圾回收机制有两种,一种是标记清除,一种是引用计数。后者有一个问题,就是遇到循环引用,会造成内存泄漏。不再用到的内存,没有及时释放就叫作内存泄漏。如果初始化一个全局变量,后面的代码没有用到这个变量也会造成内存泄漏。

管理内存

  一旦数据不再有用,最好通过将其设置为null来释放其引用,这个做法叫作解除引用。这个做法适用于大多数的全部变量和全局对象。不需要用在局部变量上,因为局部变量会在它们离开执行环境时自动被解除引用。不过解除一个值的引用并不意味着自动回收该值所占用的内存。解除引用的真正作用是让值脱离执行环境,以便垃圾收集器下次运行时将其回收。
疑问:
1 执行环境(execution context) 和作用域 (scope)的区别在哪里?
网上看了好多文章都是在解释 执行环境 和 作用域链(scope chain) 之间的关系, 很少有解释执行环境和作用域(scope)之间的区别的. 为什么js高级程序设计上只保留了执行环境这个概念, 而没有提到作用域(scope)这个概念, 只提了作用域链(scope chain)

2 变量对象(variable object)和活动对象(activation object)的区别在哪里

3 执行环境作为一个抽象概念, 每个执行环境都有一个与之关联的变量对象(variable object).
但是为什么js高级程序设计(第三版)上会说: "在web浏览器中, 全局执行环境被认为是window对象" 全局执行环境不是一个抽象概念吗, 为什么又会"被认为是window对象"呢? 一个 抽象概念 怎么成了一个 具体的window对象 呢?
它这句话的意思是不是在说:"与全局执行环境相关联的变量对象是window对象" ? 对象 是 对象. 这样好像就能理解了
还有就是js高级程序设计(第三版)还说:"this引用的是函数据以执行的环境对象" 这个"环境对象"又是个什么概念, 也是指与函数的执行环境相关联的那个变量对象吗?
4 函数中的[[scope]]属性又该怎么理解
5 如果可以的话也请讲讲eval函数形成的执行环境
6 这些和所谓的词法作用域有关系吗?
https://www.zhihu.com/question/51336888

相关文章

网友评论

      本文标题:作用域和内存问题

      本文链接:https://www.haomeiwen.com/subject/ubndjqtx.html