javascript高程笔记-------第四章 变量作用域和内存问题

Posted 迷~途

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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的方式进行解除引用

以上是关于javascript高程笔记-------第四章 变量作用域和内存问题的主要内容,如果未能解决你的问题,请参考以下文章

跟我学《JavaScript高程3》第一讲,课程笔记

跟我学《JavaScript高程3》第一讲,课程笔记

JAVASCRIPT高程笔记-------第五章 引用类型

ArcGIS API for JavaScript 4.2学习笔记[30] 点和线高程查询(第八章完结)

高程笔记

JS高程读书笔记-第一二章-内附在线思维导图和quizlet卡片