美文网首页
javascript变量、作用域和内存问题

javascript变量、作用域和内存问题

作者: 索伯列夫 | 来源:发表于2018-10-04 23:59 被阅读0次

    早期的博客1
    javascript变量松散类型的本质,决定了它只是在特定时间用于保存特定值的一个名字而已。

    一、基本类型与引用类型的值

    1.1 基本类型值:指的是简单的数据段。

    1.1.1 五种基本基本数据类型:undefined、null、boolean、number、string。

    1.1.2 按值访问。因为可以操作保存在变量中的实际的值。

    1.2 引用类型值:可能由多个值构成的对象

    1.2.1 引用类型的值是保存在内存中的对象。

    1.2.2 按引用访问。因为javascript不允许直接访问内存中的位置,在操作对象时,实际上在操作对象的引用而不是实际的对象。

    1.3 动态的属性:只能给引用类型值动态的添加属性

    1.4 复制变量值: 针对基本数据类型值得复制,会在栈中创建一个新值,然后把该值复制到新变量分配的位置上,针对引用类型值时,复制的只是一个指针,复制操作结束后,两个变量实际上将引用同一个对象。

    1.5 参数传递:所有的参数传递都是按值传递。虽然访问变量的时候有按值和按引用两种方式,但是参数只能按值传递。在向参数传递引用类型的时候,会把这个值在内存中的地址复制给一个局部变量,因此这个局部变量的变化就会反应在函数的外部。(可以把ECMAScript函数的参数想象成局部变量)

    1.6 检测类型 :typeof操作符是确定一个变量是字符串、数值、布尔、还是undefined,以及object的最佳工具,但是对于一个对象或者null,却只能返回“object”,因此在检测引用类型值得时候,引入instanceof操作符。

    function Name(){
    }
    var p = new Name();
    alert(p instanceof Name); //true
    

    二、执行环境以及作用域

    2.1 执行环境定义了变量和函数有权访问的其他数据,每个执行环境都有一个变量对象,环境中的所有变量和函数都保存在这个对象中,我们编写的代码无法访问这个对象。

    2.2 全局执行环境:最外围的一个执行环境,在web浏览器中,全局执行环境就是window对象,因此全局变量和函数都作为window对象的属性和方法创建。

    2.3 当某个执行环境的所有代码执行完毕后,该环境会被销毁,保存在其中的变量和函数也会被销毁。

    2.4 全局执行环境的销毁是在关闭网页或者浏览器时。

    2.5 每个函数都有自己的执行环境,当执行到某个函数时,会把控制权交给该函数,直到函数执行完毕后,再把控制权交给之前的环境。

    2.6 当代码在一个环境(例如一个函数)中执行时,会创建变量对象的作用域链。

    2.7 作用域链的作用是保证对执行环境的变量和函数有序访问。

    2.8 作用域链的前端始终是当前代码的执行环境的变量对象。

    2.9 如果执行环境是函数,那么变量对象是活动对象,初始只包含一个变量arguments对象,外层是包含该环境的环境,一直延伸到全局执行函数。

    2.10 全局执行环境始终是作用域链的最后一个对象。

    2.11 在搜索某个表示符(如变量名,函数名等)时,会沿着作用域链一级一级的搜索,直到找到,搜索停止,这也就达到了2.7中提到的作用域链的作用(保证对执行环境中的变量和函数的有序访问)

    2.12 内部环境可以通过作用域链一级一级访问所有外部的变量以及函数,包括最外层的全局执行环境,但是外部环境却不能访问到内部环境的变量和函数,作用域链只能向下搜索,不能从下向上搜索。

    2.13 延长作用域链的方式: 第一try-catch语句中的catch块,第二with语句。这两个语句都会在作用域链的前端添加一个变量对象,对于with语句来说,其变量对象中包含着为指定对象的所有属性和方法所做的变量声明。对于catch语句,其变量对象中包含的是被抛出的错误对象的声明,这些变量对象是只读的。

    2.14 浏览器兼容问题,注意ie与标准在try-catch语句延长作用域链的不同之处,即使在catch块的外部也可以访问到错误对象。

    2.15 javascript没有块级作用域的概念,所谓块级作用域就是由花括号封闭的代码块都有自己的作用域,但js中使用var声明的变量,会被自动添加到距离最近的可用的执行环境中,未使用var声明被初始化的变量,会被自动添加到全局环境,其作用范围跟花括号没有关系。

    2.16 查询标识符时也会根据作用域链,从下向上一级一级进行搜索,搜索到后,就停止,因此,如果局部环境存在同名的标识符,就不会使用父环境中的标识符。

    三、垃圾回收机制

    3.1 javascript具有自动垃圾收集机制,垃圾收集器会按照固定的时间间隔周期性的执行这一操作,两种方式:标记清除和引用清除

    3.2 标记清除:js中最常用的垃圾收集方式,当执行流进入到相应的环境(即执行流调用某个函数)时,该函数中声明了变量,那么这个变量就被标记为“进入环境”,从逻辑上讲,不能释放进入环境的变量的内存,当变量离开环境时,则被标记为“离开环境”。可利用翻转某个特殊的位来记录。

    3.3 引用计数:跟踪记录每个值被引用的次数。

    3.4 循环引用:对象A包含一个指向对象B的指针,而对象B中也包含一个指向对象A的指针,就形成了循环引用。在不适用它们的时候,手工断开它们的连接。

    3.5 内存限制问题:js中分配给web浏览器的可用内存数量通常比分配给桌面应用程序的少,原因是为了防止运行js的网页耗尽全部内存导致系统崩溃。

    3.5 解除引用: 由于内存的限制,所以我们要优化内存占用,最佳策略是执行代码只保存必要的数据,一旦数据不再用,最好通过将其设置为null来释放对其的引用,称为解除引用。适用于大多数全局变量和全局对象的属性,局部变量会在它们离开执行环境时自动被解除引用。解除引用并不代表收回该值所占的内存,解除引用的真正作用是让值脱离执行环境,以便垃圾收集器下次运行时将其收回。

    相关文章

      网友评论

          本文标题:javascript变量、作用域和内存问题

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