资讯专栏INFORMATION COLUMN

值类型、执行环境和垃圾回收

darkbaby123 / 2465人阅读

摘要:中的变量是松散类型的即它在不同的时期可以有不同类型的值这也是最强大的的特性之一基本类型和引用类型的值的值类型有两种基本类型引用类型。

ECMAscript中的变量是松散类型的,即它在不同的时期可以有不同类型的值,这也是ECMAscript最强大的的特性之一.

基本类型和引用类型的值

javascript的值类型有两种:基本类型 引用类型。基本类型的值是指的简单的数据段,基本类型有五种,依次是:Undefined Boolean String Number Null,而引用类型的值指的是由多个值构成的对象.

基本类型值和引用类型值的区别 保存方式不同

基本类型值的变量是保存确实的值.而引用类型值的变量保存的是一个指针,这个指针指向内存中的对象.

引用类型的值可以动态添加属性和方法. 复制形式不同

当基本类型值的变量被复制给另一个变量时,内存中会新开辟一个存储空间来存储这个新变量的值,新变量的值和被复制的变量的值保存在两个不同的存储空间中,它们相互独立,互不影响.

当引用类型值的变量被复制给另一个变量时,内存中不会开辟新的空间,新变量保存的也是一个指向内存中对象的指针,新变量和旧变量指向的是同一个存储区域,因此改变其中一个变量的值,另一个变量也会随之改变.

var name = "yuhualingfeng";
var anotherName = name;
alert(anotherName);  // yuhualingfeng

anoherName = "Jake";
alert(anotherName); // Jake
alert(name); //yuhualingfeng 

如上所示,改变了anotherName的值并没影响到name变量的值.

var obj = new Object();
obj.name = "yuhualingfeng";

var anotherObj = obj;

alert(anotherObj.name); // yuhualingfeng

anotherObj.name = "Jake";

alert(anotherObj.name); // Jake
alert(obj.name);  Jake

改变anotherObj对象的name属性值后,obj对象的name属性值也随之改变,这一点可以判断出二者指向的是同一个存储区域.

执行环境(作用域)

执行环境是Javascript中最为重要的一个概念.执行环境定义了变量或函数有权访问的其他数据,定义了它们各自的行为.每个执行环境都有一个与之关联的变量对象

全局执行环境是最外层的执行环境,全局执行环境中有一个window全局对象,全局环境中的所有变量都可以通过window对象访问.

除全局执行环境外,每个函数也都有一个自己的执行环境.当执行某个函数时,会产生一个由变量对象组成的作用域链,作用域链的存在是为了让解析器能够有序的找寻标识符,假如在函数中使用某个变量时,首先解析器会在函数自身的变量对象中找寻这个变量的标识符,假如没找到,会继续查找上一个变量对象,直到找到这个标识符为止.查找标识符时,
解析器会从作用域链中函数自身的变量对象开始寻找,直至全局执行环境中的变量对象,假如在全局环境中的变量对象中没找到标识符,解析器就会抛出错误.

var age = 30;

function changeAge(){

age = 40;

}

changeAge();

alert(age); // 40

changeAge的作用域链中有两个变量对象,自身的变量对象和全局环境的变量对象,当执行changeAge函数时,调用了age变量,解析器先在changeAge变量对象中查找此变量,没有找到,然后继续查找上一个变量对象全局变量对象,找到了age变量.

有一点要注意的是,javascript中的作用域和其他编程语言不同,它没有块级作用域,看下面的例子:

function test(){

      for(var i = 0,len =10;i < len;i++){
    doSomething(i);
    console.log(i); //  10
    }

}
test();

在for语句中定义的i变量,在for语句外可以被访问到.javascript中定义的变量会把它添加到最近执行环境的变量对象中.这里会把i变量添加到test函数的变量对象中.

垃圾收集

Javascript具有自动垃圾收集机制,执行环境会负责管理代码执行过程中使用的内存.

垃圾回收机制的原理:垃圾收集器找出那些不再继续使用的变量,然后释放其占用的内存,垃圾收集器会按固定的事件周期性的执行内存回收.

用于标记无用变量策略因实现而异,具体到浏览器中的插件,通常有以下两种策略:标记清楚 引用计数

标记清除

标记清除是浏览器中最常用的一种垃圾收集方式.当变量进入环境时(例如用var 声明一个变量),就将这个变量标记为进入环境,当变量离开环境时,就将这个变量标记为离开环境,当然,做这种标记的方式可以有多种,比如可以通过翻转某个特殊的位来记录变量合适进入环境,或者使用一个"进入环境的"变量列表及一个"离开环境的"变量列表来跟踪哪个变量发生了变化.

垃圾回收器会给所有存储在内存中的变量都加上标记(进入环境),当变量在执行环境中无法被访问到时,就会加上另一种标记(离开环境),待下一次垃圾回收器进行回收时将回收其占用的内存.

引用计数

另一种不太常见的回收方式是引用计数.引用计数就是计算出变量被引用的次数,当一个变量被赋值为一个引用类型的值时,引用类型值的引用次数就加1,当这个变量指向另一个引用类型的值时,引用类型值的引用次数就减1.当垃圾回收器进行检测时,发现引用类型的值被引用的次数等于0时就会回收其占用的空间.
这种垃圾回收机制会在循环引用中导致严重的内存泄露,看下面例子:

function Test(){
    var obj1 = new Object();
  var obj2 = new Object();
  
  obj1.property = obj2;
  obj2.property = obj1;
}

Test函数执行完成后,通过引用计数的机制进行垃圾回收时,会发现obj1指向的引用类型值的引用计数为1(被obj2.property引用),obj2指向的引用类型值的引用计数为1(被obj1.property引用),因此这两个引用类型的值就不会被回收,假如多次执行此函数就会造成严重的内存泄露.
为了解决这个问题需要手动释放内存:

obj1.property = null;
obj2.property = null;

IE浏览器中IE9以前的版本的BOM和DOM中的对象采用的就是引用计数的回收机制,因此我们在使用时需格外注意.
还有一点需要注意的是:全局环境中的变量只会在应用程序结束(比如关闭浏览器)时才会离开执行环境,所以我们需要尽可能的手动释放无用的变量占用的内存.

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/92335.html

相关文章

  • 《Javascript高级程序设计 (第三版)》第四章 变量、作用域内存问题

    摘要:在中虽然对象通过标记清除的方式进行垃圾收,但与对象却是通过引用计数回收垃圾的,也就是说只要涉及及就会出现循环引用问题。如果垃圾收集例程回收的内存分配量低于,则变量字面量和或数组元素的临界值就会加倍。 只挑本人重要的写(有夹杂其他补充) 基本类型和引用类型的值 描述:基本类型值指的是简单的数据段,而引用类型值指那些可能由多个值构成的对象。 动态的属性 引用类型的值,我们可以为其添加属性和...

    szysky 评论0 收藏0
  • 《JS高程3》—— 内存回收垃圾收集、内存泄漏

    摘要:局部变量只在函数执行过程中存在。此时,局部变量就没有存在的必要了,因此可以释放它们的内存以供将来使用。总结一般情况下,局部变量的生命周期为函数对象执行到执行结束,全局变量的生命周期为浏览器打开和关闭。 垃圾收集 JavaScript具有自动垃圾收集机制,也就是说,执行环境会负责管理代码执行中使用的内存。在C和C++语言中,开发人员一项基本任务就是手工跟踪内存的使用情况,这是造成许多问题...

    qujian 评论0 收藏0
  • JavaScript学习笔记 - 变量、作用域与内存问题

    摘要:语句中的块语句对来说,将会指定对象添加到作用域链中。在严格模式下,初始化未经声明的变量会导致错误。查询标识符搜索过程从作用域链的前端开始,向上逐级查询与给定名字匹配的标识符。 本文记录了我在学习前端上的笔记,方便以后的复习和巩固。 4.1基本类型和引用类型的值 ECMAScript变量可能包含两种不同数据类型的值:基本类型值和引用类型值。基本类型指的是简单的数据段,而引用类型值指那些可...

    lavnFan 评论0 收藏0
  • JS学习笔记(第4章)(变量、作用域内存问题)

    摘要:具体来说就是当执行流进入下列任何一个语句时,作用域链就会得到加长语句的块和语句。这两个语句都会在作用域链的前端添加一个变量对象。对来说,会将指定的对象添加到作用域链中。 1. 基本类型和引用类型的值 JavaScript变量可以用来保存两种类型的值:基本类性值和引用类性值。基本类型值源自以下5种基本数据类型:Undefined、Null、Boolean、Number和String。基本...

    linkin 评论0 收藏0
  • 复习Javascript专题(二):闭包,内存,以及垃圾回收机制

    摘要:一个闭包就是当一个函数返回时,一个没有释放资源的栈区所以参数和变量不会被垃圾回收机制回收。使用不当会很容易造成内存泄露。最后,垃圾回收器完成内存清除工作,销毁那些带标记的值并回收它们所占用的内存空间。 1.什么是闭包?闭包有啥特性以及存在什么问题? 概念:闭包是指有权访问另一个函数作用域中的变量的函数。下面的outer就形成了一个闭包: function outer(){ co...

    hankkin 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<