zoukankan      html  css  js  c++  java
  • javascript高程笔记-------第四章 变量、作用域和内存问题

       首先JavaScript中的变量分为基本类型和引用类型。

     基本类型就是保存在栈内存中的简单数据段,而引用类型指的是那些保存在堆内存中的对象。

    1.参数传递

    javascript中所有参数的传递都是值传递。

    1.1 基本数据类型的传递(undefined ,Null,Boolean,number,String)

    1--->var money = 10;

    2--->var t=function (money){
    money = 5;
    alert(money); //5
    }
    3--->t(money);

    4--->alert(money); //10

    执行过程 ①全局环境中初始化money的值 为10  ; ②创建函数 t 的执行环境  ;③ 执行 t 函数  复制全局环境中money的变量的值    赋值给 t 函数中的money    函数体内的money被改变 为5   然后再执行④  全局中的money值依然为10

    1.2 对象的传递 (传递是对象的引用地址)

    1--->var person = new Object();
    2--->var student = person; 
    3--->student.name = "zhangsan";
    4--->alert(person.name); // zhangsan

     执行过程 ①全局环境中初始化person ,person引用了栈区的一个空对象  ; ②将person引用的对象地址值复制一份   赋值给student   ;③ 将student引用的对象中添加name属性 赋值为 zhangsan   ④  由于student和person引用的是同一个对象  所以值为 zhangsan!

     示例图


    1.1 作用域链

      在浏览器中顶层的容器为window对象, 执行某段js函数时,函数内部使用的对象,首先在函数内部寻找,未找到则向上延伸至函数体外部查找,直到找到要使用的对象;

    1.2 没有块级作用域

    javascript 中的 if 和 for循环  内部定义的变量  将会扩充至作用域链的上一层 变量 

    示例 : for循环内部定义的b和i  在aa函数中 依然可以被访问到 

    function aa(){
    	for(var i=0; i<5;i++){
    		var b = i;
    	}
      alert(i) ;   //5
      alert(b);  //4
    }
    

    1.3 变量、查询标识符

     声明方式:  ①使用var 关键字  此时变量的作用范围默认在当前执行环境内部    ② 不使用var    那么这个变量将存在余全局windon对象当中

    当某个函数 引用一个变量时 ,必须通过搜索来确定引用变量的值,搜索过程从当前的执行环境逐步向上寻找整个作用域链 ,找到了该变量的定义则使用已定义的值,如未找到则认为该变量的值为undefined , 

    var b = 5;
    function a(){
    	alert(b);  //5
    }
    

     当 执行环境内部与作用域链中 存在同名变量时候  则使用离执行环境最近的值 

    var b = 5;
    function a(){
      var b=10;
    	alert(b);  //10
    }
    

      1.4 垃圾回收

    javascript具有自动收集垃圾机制,但不同的浏览器有不同的实现方式   

    ① 标记清除(mark-and-sweep),当变量进入执行环境(函数体内声明一个变量) 就将这个变量标记“进入环境”,而当变量离开环境时(0函数体执行完毕)标记“离开环境” ,大部分浏览器都是使用此方式进行垃圾回收 (截至2008年,IE,Firefox,Opera,Chrome,Safari)或类似回收策略,回收时间的周期不同而已

    ②引用计数 (reference counting): 当声明一个变量a ,将这个变量a赋值给另外一个变量b时  变量a被引用次数+1,当又将a的值赋给其他变量c时 ,a被引用的次数再+1,当程序继续执行  变量c的值 引用其他值时  ,则变量a的引用次数-1,再然后 变量b的值也不等于变量a时 ,变量a被引用的次数再-1 

    当引用次数为0时,说明不会再有任何执行环境需要变量a,因此就可以回收其占用的内存,

    引用计数带来的问题---------当存在互相引用时(循环引用),将无法回收被占用的内存,导致内存泄漏

    function a(){
    	var element = document.getElementById("somthingElement");
    	var myObject = new Object();
    	myObject.element = element;
    	element.someObject = myObject;
    }
    

      此时 a() 函数执行完毕后  element 与myObject互相引用  两者的引用次数都为1 因此无法释放其占用的内存 ,

    不管浏览器采用如何的垃圾回收策略,程序内部最好的解决方式仍然是手动解除对象的引用:

    function a(){
    	var element = document.getElementById("somthingElement");
    	var myObject = new Object();
    	myObject.element = element;
    	element.someObject = myObject;
    	//coding.....
    	myObject.element = null;
    	element.myObject = null;
    }
    

      在IE9中采用了纯JavaScript对象方式实现BOM和DOM  ,避免了循环引用带来的内存泄漏!

     性能优化: 最佳方式就是在执行的代码中只保存有效数据,一旦确定数据不在使用,通过设置为null的方式进行解除引用

  • 相关阅读:
    应用开发框架之——业务规则脚本化
    tms脚本演示代码之一
    根据.DFM文件动态生成窗体以及在之前先必须注册窗体中使用到的类
    界面/业务规则脚本化
    delphi 脚本引擎比较
    html5 datalist 选中option选项后的触发事件
    Laravel 5.6 模型关联 user 表后查询 user 表数据只能获取第一条数据,不知道怎么获取第二条...
    小技巧两个感叹号(两个!)连用
    Bootstrap 字体图标(Glyphicons)
    使用withCount后再使用select设置查询的字段。就找不到withCount的数据了
  • 原文地址:https://www.cnblogs.com/shenwenbo/p/7613278.html
Copyright © 2011-2022 走看看