JS变量、作用域、内存问题(摘至javaScript高程3)
2018-01-30 11:39
531 查看
基本数据类型和引用数据类型
基本数据类型:简单的数据段,其数据类型是按值访问,可以操作保存变量中的实际值。存放形式 是以栈的方式存放。引用数据类型:多个值构成的对象,其值是保存在内存中的对象。存放形式是以堆的形式存放。
ES中所有函数的参数都是按值传递的,即把函数外部的值复制给函数内部。
基本类型的值传递如同基本类型的变量复制一样,
引用类型值的传递,如同引用类型变量的复制一样。
在向参数传递基本类型的值时,被传递的参数会被复制给一个局部变量。
在向参数传递引用数据类型的值时,会把这个值在内存中的地址复制给一个局部变量,因此其局部变量的变化会反映在函数的外部。
//基本数据类型的 值传递 function addTen(num){ num += 10; return num; } var count = 20; var person = addTen(count); console.log(count) //20 console.log(person) //30
//引用数据类型 的值传递 function addTen(obj){ obj.name = 'lose' } var person = new Object(); addTen(person) console.log(person.name) //lose
//引用数据类型 的值传递 function addTen(obj){ obj.name = 'lose'; obj = new Object(); obj.name = 'amy'; } var person = new Object(); addTen(person) console.log(person.name) //lose
注:引用数据类型依然是按值传递,当在函数内部重写了obj时,这个变量引用的就是一个局部对象了,而这个局部对象会在函数执行完毕后立即销毁。
检测类型
基本数据类型用 typeof 可以直接检测;引用数据类型用instanceof检测;用法如下:
console.log(person instanceof Object) //变量person是对象吗
所有引用类型的值都是Object的实例,检测一个引用数据类型和Object构造函数时,instanceof 操作符始终会返回true。
反之,用instanceof 检测一个基本数据,始终会返回false,因为基本数据类型不是对象。
执行环境与作用域
执行环境定义了变量或函数有权访问的其他数据,每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中。全局执行环境是最外围的一个执行环境。在web浏览器中,全局执行环境被认为是window对象,因此所有全局变量和函数都是作为window对象的属性和方法创建的。某个执行环境的所有代码执行完毕后,该环境被销毁,保存在其中的函数定义和变量也随之销毁。(全局执行环境,直到某个应用退出时才会被销毁)
当代码在一个环境中执行时,会创建变量对象的一个作用域链。其用途是为了保证对执行环境有权访问所有变量和函数的有序访问。
var color = 'blue'; function changeColor(){ if(color === 'blue'){ color = 'red'; }else{ color = 'blue'; } }; changeColor(); console.log('color is ' + color); //color is red
举个栗子:
var color = 'blue'; function changeColor(){ var anotherColor = 'red'; function other(){ var tempColor = anotherColor; anotherColor = color; color = tempColor; //可以访问tempColor,color,tempColor } //可以访问 color,anotherColor,不能访问tempColor other(); } //可以访问color,不能访问anotherColor,tempColor changeColor();
以上代码涉及3个执行环境:全局,changeColor() 局部环境,other() 局部环境;
内部环境可以通过作用域链访问外部的所有环境,但外部环境不能访问内部环境的任何变量和函数。
这些环境之间的联系是线性的、有次序的,每个环境都可以向上搜索作用域链,以查询变量和函数名;但任何环境都不能通过向下搜索作用域链而进入另一个执行环境。
js没有会块级作用域
举个栗子:if(true){ var color = 'blue'; } console.log(color) //blue
if语句的变量声明会将变量添加到当前的执行环境中(全局环境);
例如在 for 语句中:
var doSomething = function(){ } for(var i = 0; i<10; i++){ doSomething(i); } console.log(i) //10
for语句创建的变量i即使在for循环结束后,也依旧会存在于循环外部的执行环境中。
1,声明变量
如果初始化变量时没有使用var声明,该变量会自动添加到全局环境中.
function sun(num1,num2){ a = num1 + num2; return a; } var rest = sun(10,20); console.log(a); //30 console.log(rest); //30
2,查询标识符
举个栗子:
var col = 'blue'; function find(){ return col; } console.log(find()); //blue
首先,搜寻 find() 的变量对象,找寻其中是否包含一个 名为 col 的标识符;
如果没有,则继续找下一个变量对象(全局对象),找到以后,搜索停止。
如果局部环境中存在同名标识符,则不会使用位于父环境的标识符
举个例子:
var col = 'blue'; function find(){ var col = 'red'; return col; } console.log(find()); //red console.log(window.col); //blue
任何位于局部变量声明后的代码,如果不使用 window.都无法访问全局变量。
如果有一个操作数是对象,而另一个不是,就会在对象上调用 valueOf() 的方法取得基本类型的值。
垃圾收集
JS具有自动垃圾收集机制。1 : 标记清除
2 : 引用计数
3:管理内存
优化内存占用的最佳方法,为执行中的代码只保存必要的数据,一旦数据不再拥有,通过将其值设置为null来释放引用,该方法被称作为接触引用。
举个栗子:
function content(name){ var loctionPerson = new Object(); loctionPerson.name = name; return loctionPerson; } var restFun = content('lose') //手动解除restFun 的引用 restFun = null;
注:解除一个值的引用,并不意味着自动回收该值所占用的内存。解除引用的真正作用是让值脱离执行环境,以便垃圾收集器下次运行时将其回收。
相关文章推荐
- JS高级程序设计4-变量、作用域、和内存的问题
- javascript 基础笔记 变量、作用域、内存问题
- Javascript学习笔记04 ——变量,作用域,内存问题
- javascript 基础笔记 变量、作用域、内存问题
- 学习 javascript高级程序设计 (第3版)-- 变量、作用域、内存问题
- 读书笔记 - js高级程序设计 - 第四章 变量 作用域 和 内存问题
- JavaScript中变量、作用域、内存问题
- javascript之变量作用域内存问题
- JavaScript中变量、作用域、内存问题
- js变量作用域和内存问题
- javascript高级程序设计(第3版) 读书笔记2 变量,作用域 内存问题
- js高程第四章 变量、作用域和内存问题------学习笔记
- JavaScript基础(2)变量,作用域和内存问题
- js高级程序设计(四)变量、作用域和内存问题
- Javascript学习笔记3——变量、作用域和内存问题
- JavaScript学习笔记 -- 变量作用域问题
- 有关js的变量、作用域和内存问题
- javaScript 变量 作用域和 内存问题
- 栋栋晓11:Javascript学习总结:变量、作用域和内存问题
- javascript高级程序设计第四章 变量、作用域和内存问题