JavaScript笔记:变量、作用域和内存问题
来源:互联网 发布:网络效应2017试题答案 编辑:程序博客网 时间:2024/05/22 02:23
根据ECMA-262的定义,javascript的变量和其他语言的变量有很大区别。javascript松散变量的本质,决定了它只是在特定时间内保存着特定值的名字而已。由于不存在某个变量必须要保存某个特定类型的值的规则,一个变量的值和类型可以在脚本的生命周期内改变。
1、基本类型和引用类型的值
ECMAScript变量可能包含两种不同数据类型的值:基本类型和引用类型。
基本类型值指的是简单的数据段,引用类型值指的是那些可能由多个值组成的对象。
基本数据类型包括:Undefined Null Boolean Number String。是按值访问的。
引用类型的值是保存在内存中的对象。和其它语言不同,JavaScript不允许直接访问内存中的位置,也就是说,不能直接操作对象的存储空间。在操作对象时,实际上是在操作对象的引用而不是对象。
1、动态的属性
只能为引用类型添加属性,基本类型添加的属性我们访问不到:
var person = new Object(); person.name = "Nicholas"; alert(person.name); //"Nicholas"var name = "Nicholas";name.age = 27;alert(name.age); //undefined
2、复制变量值
引用类型的复制只是复制了地址,相当于多了一个指向这块内存的引用。
var obj1 = new Object();var obj2 = obj1;obj1.name = "Nicholas";alert(obj2.name); //"Nicholas"
3、传递参数
ECMAScript中所有函数的参数都是值传递的。
在向参数传递基本类型的值时,被传递的值会赋值给一个局部变量。在向参数传递引用类型的值时,会把这个值在内存中的地址复制给一个局部变量,因此这个局部变量的变化,会反映到函数外面。
例子:
function addTen(num) { num += 10; return num; }var count = 20;var result = addTen(count); alert(count); //20alert(result); //30function setName(obj) { obj.name = "Nicholas";}var person = new Object();setName(person);alert(person.name); //"Nicholas"//证明值传递function setName(obj) { obj.name = "Nicholas"; obj = new Object(); obj.name = "Greg";}var person = new Object();setName(person);alert(person.name); //"Nicholas"
4、检测类型
var s = "Nicholas";var b = true;var i = 22;var u;var n = null;var o = new Object();alert(typeof s);alert(typeof i);alert(typeof b);alert(typeof u);alert(typeof n);alert(typeof o);// 输出结果//string//number//boolean//undefined//object//object
typeof是检测基本数据类型的好帮手,但是对于引用类型,我们应该使用instanceof方法:
alert(person instanceof Object); alert(colors instanceof Array);alert(pattern instanceof RegExp);
当然,如果用instance来检测基本类型,则始终会返回false。
2、执行环境和作用域
执行环境,是JS中很重要的一个概念。执行环境定义了函数或者变量有权访问的其它数据。
在web浏览器中,全局执行环境被认为是window对象。
某个执行环境中的所有代码运行完毕后,该环境被销毁,其中的代码和函数也都被销毁(全局环境则当应用程序退出时才被销毁)。
每个函数都有自己的执行环境。当执行流进入一个函数时,函数的环境会被推入一个环境栈中。函数执行完毕后,环境从栈中弹出,把控制权返还给之前的环境。
当代码在一个环境中执行时,会创建变量对象的一个作用域链。作用域链的作用,是保证对执行环境有权访问的变量和函数的有序访问。
标识符解析是沿着作用域链一级一级的搜索标识符的过程。搜索过程从作用域链的最前端开始(当前执行环境),直到找到标识符为止,如果找不到,则通常会报错。
例子:
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();
1、延长作用域链
当执行流进入下面任意一个语句时,作用域链就会得到加长。
1、try-catch 语句的catch块
2、with语句
function buildUrl() { var qs = "?debug=true"; with(location){ var url = href + qs; } return url; }
2、没有块级作用域
在其它语言中,由花括号包裹的部分就是一个独立的执行环境,括号内的语句执行完毕后,里面定义的变量会被销毁。然而,JS没有块级作用域的概念,就导致了下面这样的代码也不会报错。
if (true) { var color = "blue";}alert(color); //"blue"for (var i=0; i < 10; i++){ doSomething(i);}alert(i); //10
1、声明变量
使用var声明的变量会被自动加入到最近的执行环境中去。如果初始化时没有使用var声明,则改变量就会被自动加入到全局变量中。
2、查询标识符
查询顺序是沿着作用域链向上搜索:
// 实例代码1var color = "blue";function getColor(){ return color;}alert(getColor()); //"blue"// 实例代码2var color = "blue";function getColor(){ var color = "red"; return color;}alert(getColor()); //"red"
3、垃圾收集
JS具有自动垃圾清理的机制,也就是说,执行环境会负责管理代码执行过程中的内存。这种垃圾收集的机制的原理其实很简单:找出那些不再使用的变量,然后释放掉它们占用的内存。为此,垃圾收集器会周期性的执行这个操作。
1、标记清除
JS最常用的垃圾收集方式就是标记清除。当一个变量进入环境时,就将变量标记为“进入环境”。当变量离开环境时,则标记为“离开”。
垃圾收集器在运行的过程中会给所有内存中的变量都加上标记,然后,它会去掉环境中的变量以及被环境中的变量引用的变量的标记。而在此之后,再被加上标记的变量将被视为准备删除的变量,因为环境中的变量已经无法访问到这些变量了。最后,垃圾处理器完成内存清理工作,销毁那些带标记的值,并回收它们的存储空间。
2、引用计数
引用计数是一种不太常见的垃圾收集策略。引用计数的策略是跟踪记录每个值被引用的次数。当某个变量的引用计数为0时,表示该变量已经无法被访问了,则改变量可以被回收。
3、管理内存
使用具备垃圾收集机制的语言编写程序,开发人员一般不用操心内存管理的问题。但是,确保使用最少的内存可以让页面获得更好的性能。优化内存占用的最好方式,就是为执行中的代码只保存最少的数据。一旦数据不再使用,最好通过将其设置为null来释放其引用。局部变量会在它们离开执行环境后自动被解除引用。
function createPerson(name){ var localPerson = new Object(); localPerson.name = name; return localPerson; }var globalPerson = createPerson("Nicholas"); // 解除globalPerson的引用globalPerson = null;
- JavaScript笔记:变量、作用域和内存问题
- JavaScript高级程序设计笔记-变量、作用域和内存问题
- 【JavaScript】变量、作用域和内存问题
- JavaScript 变量、作用域和内存问题
- JavaScript-变量、作用域和内存问题
- javaScript 变量 作用域和 内存问题
- Javascript变量、作用域和内存问题
- JavaScript变量、作用域和内存问题
- javascript 基础笔记 变量、作用域、内存问题
- JavaScript变量,作用域与内存问题(笔记)
- JavaScript变量,作用域,内存问题(笔记)
- JavaScript高级程序设计学习笔记——变量、作用域和内存问题(重要)
- javascript高级程序设计学习笔记——第四章 变量、作用域和内存问题
- JavaScript笔记二:变量、作用域和内存
- JavaScript基础——变量、作用域和内存问题
- JavaScript学习4-JS变量、作用域和内存问题
- (深夜课堂)Javascript 变量、作用域和内存问题(1)
- JavaScript基础——变量、作用域和内存问题
- 67.Add Binary
- java.util.NoSuchElementException: Unable to validate object
- Android 跑马灯效果实现的两种方式,解决和viewpager的冲突问题
- 注册模块要注意点
- iOS - 首次安装导航页面方案
- JavaScript笔记:变量、作用域和内存问题
- java-two sum
- C++11 并发指南九(综合运用: C++11 多线程下生产者消费者模型详解)
- inparanoid
- POJ 2524Ubiquitous Religions
- 车辆保养记录查询
- css 实现文本省略号:单行多行
- Linux 常用命令
- 自定义广播(Broadcast)