JavaScript基础——变量、作用域和内存问题
2015-11-09 15:35
591 查看
JavaScript变量可以用来保存两种类型的值:基本类型值和引用类型值。
基本类型的值源自以下5种基本数据类型:Undefined、NuLL、Boolean、Number和String。
基本类型值和引用类型值具有以下特点:
1)基本类型值在内存中占据固定大小的空间,因此被保存在栈内存中;
2)从一个变量向另一变量复制基本类型的值,会创建这个值的一个副本;
3)引用类型的值是对象,保存在堆内存中;
4)包含引用类型值的变量实际上包含的并不是对象本身,而是一个指向该对象的指针;
5)从一个变量向另一个变量复制引用类型的值,复制的其实是指针。因此两个变量最终指向同一个对象;
6)确定一个值是哪种基本类型可以使用typeof操作符,而确定一个值是哪种引用类型可以使用instanceof操作符。
所有变量(包括基本类型和引用类型)都存在于一个执行环境(也称为作用域)当中,这个执行环境决定了变量的生命周期,以及哪一部分代码可以访问其中的变量。以下是关于执行环境的几点总结:
1)执行环境有全局执行环境(也称为全局环境)和函数执行环境之分;
2)每次进入一个新执行环境,都会创建一个用于搜索变量和函数的作用域链;
3)函数的局部环境不仅有权访问函数作用域中的变量,而且有权访问其包含(父)环境,乃至全局环境;
4)全局环境只能访问在全局环境中定义的变量和函数,而不能直接访问局部环境中的任何数据;
5)变量的执行环境有助于确定应该何时释放内存。
JavaScript是一门具有自动垃圾收集机制的编程语言,开发人员不必关心内存分配和回收问题。可以对JavaScript的垃圾收集例程作如下总结:
1)离开作用域的值将被自动标记为可以回收,因此将在垃圾收集期间被删除;
2)"标记清除"是目前主流的垃圾收集算法,这种算法的思想是给当前不使用的值加上标记,然后再回收其内存;
3)另一种垃圾收集算法是"引用计数",这种算法的思想是跟踪记录所有值被引用的次数。JavaScript引擎目前都不再使用这种算法;
4)当代码中存在循环引用现象时,"引用计数"算法会导致问题;
5)解除变量的引用不仅有助于消除循环引用对象,而且对垃圾收集也有好处。为了确保有效地回收内存,应该及时解除不再使用的全局对象、全局对象属性以及循环引用变量的引用。
基本类型的值源自以下5种基本数据类型:Undefined、NuLL、Boolean、Number和String。
基本类型值和引用类型值具有以下特点:
1)基本类型值在内存中占据固定大小的空间,因此被保存在栈内存中;
2)从一个变量向另一变量复制基本类型的值,会创建这个值的一个副本;
3)引用类型的值是对象,保存在堆内存中;
4)包含引用类型值的变量实际上包含的并不是对象本身,而是一个指向该对象的指针;
5)从一个变量向另一个变量复制引用类型的值,复制的其实是指针。因此两个变量最终指向同一个对象;
6)确定一个值是哪种基本类型可以使用typeof操作符,而确定一个值是哪种引用类型可以使用instanceof操作符。
所有变量(包括基本类型和引用类型)都存在于一个执行环境(也称为作用域)当中,这个执行环境决定了变量的生命周期,以及哪一部分代码可以访问其中的变量。以下是关于执行环境的几点总结:
1)执行环境有全局执行环境(也称为全局环境)和函数执行环境之分;
2)每次进入一个新执行环境,都会创建一个用于搜索变量和函数的作用域链;
3)函数的局部环境不仅有权访问函数作用域中的变量,而且有权访问其包含(父)环境,乃至全局环境;
4)全局环境只能访问在全局环境中定义的变量和函数,而不能直接访问局部环境中的任何数据;
5)变量的执行环境有助于确定应该何时释放内存。
JavaScript是一门具有自动垃圾收集机制的编程语言,开发人员不必关心内存分配和回收问题。可以对JavaScript的垃圾收集例程作如下总结:
1)离开作用域的值将被自动标记为可以回收,因此将在垃圾收集期间被删除;
2)"标记清除"是目前主流的垃圾收集算法,这种算法的思想是给当前不使用的值加上标记,然后再回收其内存;
3)另一种垃圾收集算法是"引用计数",这种算法的思想是跟踪记录所有值被引用的次数。JavaScript引擎目前都不再使用这种算法;
4)当代码中存在循环引用现象时,"引用计数"算法会导致问题;
5)解除变量的引用不仅有助于消除循环引用对象,而且对垃圾收集也有好处。为了确保有效地回收内存,应该及时解除不再使用的全局对象、全局对象属性以及循环引用变量的引用。
/* * 变量、作用域和内存问题 */ function cl(x){ console.log(x); } //4.1 基本类型和引用类型的值 //4.1.1 动态的属性 //4.1.2 复制变量值 var obj1=new Object(); var obj2=obj1; obj1.name="Jason"; cl(obj2.name); //=>"jason" //4.1.3 传递参数 function setName(obj){ obj.name="Jenny"; obj=new Object(); obj.name="Greg"; } var person=new Object(); setName(person); cl(person.name); //=>"Jenny",参数是按值传递的,而不是按引用传递 //4.1.4 检测类型 typeof:检测变量的类型,instanceof:检测是否是引用类型的实例 var s="Jason"; var b=true; var i=22; var u; var n=null; var o=new Object(); cl(typeof s); //=>string cl(typeof b); //=>boolean cl(typeof i); //=>number cl(typeof u); //=>undefined cl(typeof n); //=>object cl(typeof o); //=>object cl(person instanceof Object); //=>true //4.2 执行环境及作用域 var color="blue"; function changeColor(){ var anotherColor="red"; function swapColors(){ var tempColor=anotherColor; anotherColor=color; color=tempColor; //这里可以访问 color、anotherColor、tempColor } //这里可以访问color、anotherColor,但不能访问tempColor swapColors(); } //这里只能访问color changeColor(); // 4.2.1 延长作用域链:try-catch语句的catch块;with语句 function buildUrl(){ var qs="?debug=true"; with(location){ var url=href+qs; } return url; } //4.2.2 没有块级作用域 if(true){ var weather="sunny"; } cl(weather); //=>sunny for(var i=0;i<10;i++)/*空语句*/ ; cl(i);//=>10 //4.3 垃圾收集 //4.3.1 标记清除 //4.3.2 引用计数 //4.3.3 性能问题 //4.3.4 管理内存 function createPerson(name){ var localPerson=new Object(); localPerson.name=name; return localPerson; } var globalPerson=createPerson("Mary"); //通过将其值设置为null来手工解除globalPerson的引用 globalPerson=null;
相关文章推荐
- 浅析js中substring和substr的方法
- JS中的prototype
- Servlet对Ajax中请求处理及Json串的解析
- JSON入门之二:org.json的基本用法
- js#0基本概念
- 如何处理JSON数据中含有双引号
- JS构造函数与原型
- 使用javascript打印九九乘法表
- 深入理解js构造函数
- 2015-11-02-js
- js快速分享代码
- js中substr,substring,indexOf,lastIndexOf,split,replace的用法详解
- 最快的Json框架-Jfire-codejson解析
- anjularjs 干货+ionic +百度地图
- 比较常见的javascript中定义函数的区别
- JS----setCookie,getCookie,delCookie
- 从此不再惧怕URI编码:JavaScript及C# URI编码详解
- 浅谈JavaScript中的能力检测
- 详解JavaScript中的Unescape()和String() 函数
- extjs中gridpanel中怎么获得选中行所对应的行数,比如点击第一行时的行数是1,行所对应的数据用什么方法获得