zoukankan      html  css  js  c++  java
  • JavaScript读书笔记(4)-变量、作用域和内存问题

    1、ECMAScript数据类型分为:基本类型值和引用类型值;

    ECMAScript中所有函数的参数都是按值传递的;

    检查对象的类型:varible instanceof constructor

    Alert(person instanceof Object);

    2、  执行环境和变量

    每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中;

    全局执行环境是最外围的一个指定环境,在web浏览器中,全局执行环境是window对象,所有的全局变量和函数都是window对象的属性和方法;代码执行完毕,环境被销毁;

    每个函数都有自己的执行环境,当执行流进入一个函数时,函数的环境就会被推入一个环境栈中,而在函数执行之后,栈将其环境弹出,把控制权返回给之前的执行环境;

    当代码在一个环境中执行时,会创建变量对象的一个作用域链(scope chain)。它保证对执行环境有权访问的所有变量和函数的有序访问,作用域链的前端,始终都是当前执行的代码所在环境的变量对象。如果这个环境是函数,则将其活动对象作为变量对象,活动对象在最开始时只包含一个变量,即arguments对象,作用域链中的下一个变量对象来自包含环境,而再下一个变量对象则来自下一个包含环境,这样,一直延续到全局执行环境;全局执行环境的变量对象始终都是作用域链中的最后一个对象;

    标识符解析是沿着作用域链一级一级地搜索标识符的过程;

    (1)       延长作用域链

    有些语句可以再作用域链的前端临时增加一个变量对象,该变量对象会在代码执行后被移除;

    try-catch语句的catch块:会创建一个新的变量对象,其中包含的是被抛出的错误对象的声明;

    with语句:会将制定的对象添加到作用域链中;

    (2)       没有块级作用域

    声明变量,使用var的变量会自动被添加到最接近的环境中;初始化变量时没有使用var,该变量会自动被添加到全局环境;

    不声明而直接初始化变量时一个常见的错误做法,在严格模式下,初始化未经声明的变量会导致错误;

    查询标识符,从作用域链的前端开始,向上逐级查询与给定名字匹配的标识符,如果在局部环境中找到,搜索停止,如果在局部环境中没找到变量,则继续沿作用域链向上搜索,搜索过程将一直追溯到全局环境的变量对象;

    变量查询的代价是,访问局部变量要比访问全局变量更快;

    3、  垃圾收集

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

    原理:找出那些不再继续使用的变量,然后释放其占用的内存,垃圾收集器会按照固定的时间间隔(或代码执行中预定的收集时间),周期性地执行这一操作;

    (2)       垃圾收集器必须跟踪哪个干粮有用哪个变量没用,对于不再有用的变量打上标记,以备将来收回其占用的内存,用于标识无用变量的策略常见的有两种:标记清除和引用计数;

    (3)       标记清除,当变量进入环境时,将这个变量标记为“进入环境”,当变量离开环境时,则将其标记为“离开环境”;

    垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记,然后,它会去掉环境中的变量以及被环境中的变量引用的变量的标记,而在此之后再被加上标记的变量将被视为准备删除的变量,环境中的变量已经无法访问到这些变量了,最后垃圾收集器完成清除工作,销毁那些带标记的值并回收它们所占用的内存空间;大部分浏览器都是使用的这种策略;

    (4)       引用计数,跟踪记录每个值被引用的次数,当声明了一个变量并将一个引用类型值赋给该变量时,引用次数加1,相反,如果包含这个值引用的变量又取得了另外一个值,则这个值的引用次数减1,当引用次数变为0时,就可以将其占用的内存空间回收回来。

    存在的问题是循环引用:对象A中包含一个对象B的指针,而对象B中也包含一个指向对象A的引用;

    IE中有一部分对象并不是原生的javascript对象,BOM和DOM中的对象就是使用C++以COM对象的形式实现的,而COM对象的垃圾收集机制采用的是引用计数策略。只要IE中涉及COM对象,就会存在循环引用的问题。

    Var elemen=document.getElementById(“some_element”);

    Var myObject=new Object();

    myObject=new Object();

    element.someObject=myObject;

    上面代码中一个DOM元素(element)与一个原生JavaScript对象(myObject)之间创建了循环引用;

    为了避免此类问题,最好是在不适用它们的时候手工断开原生javascript对象与DOM元素之间的连接;

    myObject.element=null;

    element.someObject=null;

    (5)       垃圾收集器是周期性运行的,如果为变量分配的内存数量很客观,那么回收工作量是相当大的,确定垃圾收集的时间间隔是很重要的问题;

    Javascript引擎的垃圾收集例程工作方式:触发垃圾收集的变量分配、字面和数组元素的临界值为动态修正;

    管理内存,优化内存占用的最佳方式:为执行中的代码只保存必要的数据,一旦数据不再有用,最好将其设置为null来释放其引用,其实就是解除引用;这一用法适用于大多数全局变量和全局对象的属性;

  • 相关阅读:
    QOMO Linux 4.0 正式版发布
    LinkChecker 8.1 发布,网页链接检查
    pgBadger 2.1 发布,PG 日志分析
    Aletheia 0.1.1 发布,HTTP 调试工具
    Teiid 8.2 Beta1 发布,数据虚拟化系统
    zLogFabric 2.2 发布,集中式日志存储系统
    开源电子工作套件 Arduino Start Kit 登场
    Piwik 1.9 发布,网站访问统计系统
    Ruby 1.9.3p286 发布,安全修复版本
    toBraille 1.1.2 发布,Java 盲文库
  • 原文地址:https://www.cnblogs.com/xyl-share-happy/p/4562263.html
Copyright © 2011-2022 走看看