手机版

谈JavaScript执行环境、范围、垃圾收集

时间:2021-10-28 来源:互联网 编辑:宝哥软件园 浏览:

执行环境定义变量或函数可以访问的其他数据,并确定它们各自的行为。每个执行环境都有一个与之关联的变量对象。

全局执行环境是最外层的执行环境。根据实现JavaScript的宿主环境,表示执行环境的对象是不同的。在Web浏览器中,全局执行环境被视为一个窗口对象。因此,所有全局变量和函数都被创建为窗口对象的属性和方法。

变量:环境中定义的所有变量和函数都存储在这个对象中。

范围链:当代码在环境中执行时,它会创建一个可变对象的范围链。范围链的目的是确保有序地访问执行环境可以访问的所有变量和函数。范围链的前端始终是当前执行代码所在环境的变量对象。

活动对象:活动对象一开始只包含一个变量,即arguments对象。范围链中的下一个变量对象来自包含(外部)环境,而下一个变量对象来自下一个包含环境。这延续到全球执行环境;全局执行环境的变量对象总是范围链中的最后一个对象。

标识符解析:标识符解析是沿着作用域链逐级搜索标识符的过程。搜索过程总是从范围链的前端开始,然后逐步返回,直到找到标识符。

示例代码:

var color=' bluefunction ChangeColor(){ if(color==' blue '){ color=' red ';} else { color=' blue} } ChangeColor();警报(“颜色现在是”颜色);函数changeColor()的作用域链包含两个对象:它自己的变量对象(其中定义了参数对象)和全局变量的变量对象。变量颜色可以在函数内部访问,因为它可以在这个范围链中找到。

此外,在局部范围内定义的变量可以与局部环境中的全局变量互换使用。示例:

var color=' bluefunction change COlOr(){ var other COlOr=' red ';函数swapColors(){ var tempColor=other color;anotherColor=colorcolor=tempColor//可以在这里访问Color,otherColor和tempColor }//可以在这里访问color,otherColor,但不能访问tempColor swapColors();}//您只能在此访问colorchangeColor();上面的代码涉及三个执行环境:全局环境、changeColor()的句柄环境和swapColors()的本地环境。

全局变量包括一个颜色变量和一个函数changeColor()。changeColor()的局部变量包括一个变量otherColor和一个函数swapColors(),该函数可以访问全局变量中的颜色。swapColors()的局部变量中有一个变量tempColor。在swapColors()中,您可以访问全局变量中的颜色或另一个颜色变量,因为这两个环境是它的父执行环境。上述示例的范围链是:

其中,内部环境可以通过范围链访问所有外部环境,但外部环境不能访问内部环境中的任何变量和函数。环境变量之间的关系是线性有序的。每个变量只能从其上级搜索作用域链来查询变量和函数的名称,即先查询这个应用程序中变量或函数的名称,然后查询下一个更高级别的作用域链,直到到达顶层作用域。但是,没有任何环境可以向下搜索范围链并进入另一个执行环境。

参数也被视为变量,因此它们的访问规则与执行环境中的其他变量相同。

1.扩展范围链。

当执行流进入以下任一语句时,范围链被扩展:

try-Catch语句的catch块。

带语句

这两个语句在作用域的前面添加了一个变量对象。

对于with语句,指定的变量被添加到范围链中。对于catch语句,将创建一个新的变量对象,其中包含抛出的错误对象的声明。

例如:

函数buildUrl() { var qs='?debug=true ';with(location){ var URL=href QS;}返回url}with语句接收location对象,因此它的变量对象包含location对象使用的属性和方法,location对象被添加到作用域链的前端。当变量href在with语句中被引用时(实际引用是location.href),可以在当前环境变量中找到它。当引用变量qs时,它引用buildUrl()中定义的变量,该变量位于函数环境变量对象中。至于with语句的内部,定义了一个名为url的变量,因此url成为函数执行环境的一部分,并且可以作为函数的值返回。

2.没有块级范围。

在JavaScript中,封闭的花括号没有自己的作用域。请看下面的代码:

if(true){ var color=' blue ';}alert(颜色);//'blue '在JavaScript中,if/for语句创建的变量声明会将该变量添加到当前执行环境中。例如:

for(var I=0;i 10I){ DosMexing(I);} alert(I);//10垃圾收集。

与Java类似,JavaScript也有自动垃圾收集机制。执行环境负责管理代码执行期间使用的内存。编写程序时,不需要处理内存的使用,所需内存的分配和无用内存的回收已经完全实现了自动化管理。垃圾收集机制的原理是找出不再使用的变量,然后释放它们占用的内存。因此,垃圾收集器将以固定的时间间隔(或代码执行期间的预定收集时间)定期执行此操作。

在垃圾回收之前,需要判断资源是否无用,并标记不再用于未来内存恢复的变量。识别无用变量的策略通常有两种实现方式。

1标记清晰。

JavaScript中最常见的垃圾收集方法是标记清理。变量进入环境时,标记为“进入环境”;当变量离开环境时,它被标记为“离开环境”。当垃圾收集器运行时,它将标记所有使用的变量。然后,它移除环境中变量的标签和环境中变量引用的变量。之后,标记的变量将被视为要删除的变量。最后,垃圾收集器完成内存清理,销毁标记的值并恢复它们占用的内存空间。

2.参考计数。

引用计数是指每个值在跟踪记录中被引用的次数。当一个变量被声明并且引用类型值被赋给该变量时,该值的引用数为1。如果将相同的值赋给另一个变量,则该值的引用数将增加1。相反,如果包含该值引用的变量得到另一个变量,则该值的引用数减少1。当这个变量的引用次数为0时,意味着没有办法引用这个变量,所以可以回收它的内存空间。当垃圾收集器下次运行时,它将回收零引用值所占用的内存。

引用计数的一个问题是它可能导致循环引用。例如:

函数问题(){ var objA=new Object();var objB=new Object();objA.someOtherObj=objBobjB.someOtherObj=objA}在上例中,objA和objB通过属性相互引用。函数执行后,objA和objB将继续存在,其引用计数不会为0。在这种情况下,objA和objB占用的内存无法回收。

以上关于JavaScript:执行环境、范围、垃圾收集的讨论,都是边肖与大家分享的内容,希望能给大家一个参考,多支持我们。

版权声明:谈JavaScript执行环境、范围、垃圾收集是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。