有关js的变量、作用域和内存问题
来自《javascript高级程序设计 第三版:作者Nicholas C. Zakas》的学习笔记(四)
js共有5种基本数据类型:Undefined、NULL、Boolean、Number、String。5种基本数据类型是按值访问的,因此可以操作保存在变量中的实际值。而引用类型则不同,因为引用类型的值是保存在内存对象中的,而js不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间。在操作对象的时候,是在操作对象的引用而不是实际的对象。所以有“引用类型的值是按引用访问的”说法。
基本数据类型与引用类型的值的区别,总结如下:
- 我们可以给引用类型的值添加属性和方法;如:
var person = new object();
person.name = "carol";
alert(person.name); //"carol"我们不能给基本类型的值添加属性。尽管不会报错,但是访问的属性会不见,如:
var name = "carol";
name.age = 27;
alert(name.age); //undefined说明:只能给引用类型值动态地添加属性,以便将来使用。
- 基本类型值的复制是独立的,如:
var num1 = 5;
var num2 = num1; //num1和num2之间其实是独立的,相互不影响引用类型的复制时,副本实际上一个指针,这个指针指向存储在堆中的一个对象,并非独立,存在相互影响,如:
var obj1 = new object();
var obj2 =obj1;
obj1.name = "Nicholas";
alert(obj2.name); //"Nicholas"
ECMAScript中所有函数的参数传递都是按值传递的。但是需要指出的是,这个值分为“基本类型值”和“引用类型值”。为什么我这么说呢?先看两个例子:
function addTen(num) {
num += 10;
return num;
} var count = 20;
var result = addTen(count);
alert(count); //
alert(result); //num作为“基本类型值”的传递时,是独立的,即num和count互不相识。
function setName(obj) {
obj.name = "carol";
} var person = new Object();
setName(person);
alert(person.name); //"carol"obj作为“引用类型值”传递,会互相影响。
但是总结起来,就是按值传递,并非有引用传递之说。即使是obj第二种情况,还是按值传递的方式,为什么呢?你可能会说,按值传递不是不会改变实参值的吗?且分析:
function setName(obj) {
obj.name = "carol";
obj = new Object();
obj.name = "gof";
} var person = new Object();
setName(person);
alert(person.name); //“carol" 而不是”gof"当在函数内部重写obj时,这个变量引用的就是一个局部对象了。而这个局部对象会在函数执行完毕后立即被销毁。从alert的结果看,如果是引用传递,person.name的结果应该是gof而不是carol。
3. 确定一个值是那种基本类型可以使用typeof操作符,而确定一个值是哪种引用类型可以使用instanceof操作符。
全局执行环境直到应用程序退出——例如关闭网页或浏览器时才会销毁。
作用域链:
用途:保证对执行环境有权访问的所有变量和函数的有序访问。标识符解析是沿着作用域链一级一级地搜索标识符的过程。即向后回溯。内部环境可以通过作用域链访问到所有外部环境,反之不行。
js没有块级作用域。解释如下:
if (true) {
var color = "blue";
}
alert(color); //"blue"
if语句中变量声明会将变量添加到当前执行环境。在使用for循环时,尤其需要注意:
for (var i = 0;i < 10;i++) {
dosomething(i);
}
alert(i); //
用var声明的变量自动添加到最近的环境中。而没有var则添加到全局环境中。
js的垃圾收集:具有自动垃圾收集机制。常用的有标记清除和引用计数。但是引用计数会出现循环引用问题,最好是采用手动断开连接:
myObject.element = null;
element.someObject = null;
管理内存:即手工解除引用。同上js的手工断开连接。为什么要管理内存呢???其实js是具有垃圾收集机制的,按道理,开发人员是不需要操心内存管理问题的,因为对离开作用域的值将被自动标记为可回收,因此将在垃圾收集期间被删除。但js有一点特殊,出于安全方面的考虑,防止运行js的网页耗尽全部系统内存而导致系统崩溃,分配给web浏览器的可用内存数量通常要比分配给桌面应用程序的少。内存限制问题不仅会影响给变量分配内存,同时还会影响调用栈以及一个线程中能够同时执行的语句数量。确保占用最少的内存可以让页面获得更好的性能。所以有了优化内存占用之说!
优化内存占用的最佳方式:为执行中的代码只保存必要的数据。一旦数据不再有用,最好通过将其值设置为null来释放其引用——这个做法叫做解除引用。这一做法适用于大多数全局变量和全局对象的属性。局部变量会在它们离开执行环境时自动被解除引用。
注意:解除一个值的引用并不意味着自动回收该值所占用的内存。解除引用的真正作用是让值脱离执行环境,以便垃圾收集器下次运行时将其回收。
function createPerson(name) {
var localPerson = new Object();
localPerson.name = name;
return localPerson;
}
var globalPerson = createPerson("carol");
//手工解除globalPerson的引用
globalPerson = null;
学习笔记。
有关js的变量、作用域和内存问题的更多相关文章
- 第一百零六节,JavaScript变量作用域及内存
JavaScript变量作用域及内存 学习要点: 1.变量及作用域 2.内存问题 JavaScript的变量与其他语言的变量有很大区别.JavaScript变量是松散型的(不强制类型)本质,决定了它只 ...
- js 变量 作用域及内存
由于Javascript是松散型的,所以其变量只是在特定时间用于保存特定值的一个名字而已,并不存在某个变量必须保存某种类型的值的规则,变量的值以及其数据类型都可以在脚本的声明周期内改变 一.基本类型与 ...
- js的变量作用域
js不支持块级变量作用域,而是包含它们的函数的作用域, 例如: function query() { ; ; i < ; i++) { var b = i; } return b + a; } ...
- js学习--变量作用域和作用域链
作为一名菜鸟的我,每天学点的感觉还是不错的.今天学习闭包的过程中看到作用域与作用域链这两个概念,我觉得作为一名有追求的小白,有必要详细了解下. 变量的作用域 就js变量而言,有全局变量和局部变量.这里 ...
- js基础之--变量 作用域和内存问题
基本类型:Undefind Null Boolean Number String 引用类型: 对象 在操作对象时,实际上实在操作对象的引用而不是实际的对象.为此,引用类型的值是按引用访问的. 从一个变 ...
- 读书笔记 - js高级程序设计 - 第四章 变量 作用域 和 内存问题
5种基本数据类型 可以直接对值操作 判断引用类型 var result = instanceof Array 执行环境 每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这 ...
- JavaScript变量作用域和内存问题(二)
执行环境是js中特别重要的概念,是指变量或者函数可以访问其他数据,定义自己的行为.每个执行环境都有一个与之相对应的变量对象,执行环境中定义的所有变量和函数都保存在这个变量中,我们看不到这个变量,但是后 ...
- 浅谈javascript中变量作用域和内存(1)
先理解两个概念:基本类型和引用类型的值 1.基本类型和引用类型的值 (1)定义: 基本类型:指简单的数据段,比如按值访问的js五种基本数据类型undefined.null.boolean.number ...
- 浅谈javascript中变量作用域和内存(2)
1.无块级作用域 javascript没有块级作用域,这会让其他程序员在理解js代码上很痛苦.在其他很多语言,比如C,大括号括起来的代码块都有自己的作用域 举个例子 if(true) { var na ...
- js的变量作用域 ,变量提升
(function(){ a = 5; alert(window.a); var a = 10; alert(a); })(); 结果: undefined 10 代码等同于下面 var a = un ...
随机推荐
- Maven搭建SpringMVC+Hibernate项目详解
前言 今天复习一下SpringMVC+Hibernate的搭建,本来想着将Spring-Security权限控制框架也映入其中的,但是发现内容太多了,Spring-Security的就留在下一篇吧,这 ...
- ASP多行多列显示代码
<table width="98%" border="0" align="center"> <tr> <% S ...
- 转 Android中this、super的区别
在Java中,this通常指当前对象,super则指父类的.当你想要引用当前对象的某种东西,比如当前对象的某个方法,或当前对象的某个成员,你便可以利用this来实现这个目 的,当然,this的另一个用 ...
- Android环境搭建的步骤
Android 环境搭建步骤 这里简单介绍一下学习Android之后如何搭建环境的问题 一. 在搭建环境之前,首先你要先下载Java JDK(根据系统位数选择下载是64位或32位的),Eclip ...
- Java之绘制二次曲线
前面已经介绍过绘制方法.这里不再赘述. 画一下草图来看看:灰色表示X值,红色表示Y值. 在这里要值得注意的是:当我们把它们的坐标在纸上画出来时,就会觉得“有问题”了,你看A(60,20,120,100 ...
- 博客迁到CSDN
之前一直是博客园和CSDN博客同步更新 现在不在博客园继续写博客,十一国庆节假后只用CSDN博客了.祝各位访客国庆节快乐! CSDN博客地址: http://blog.csdn.net/it_liuc ...
- [zz] 使用ssh公钥密钥自动登陆linux服务器
目录 .生成密匙对 .拷贝公匙到远程机 .启动登陆代理 这种方法处理后每次需要运行命令:ssh-add ~/.ssh/id_dsa 作为一名 linux 管理员,在多台 Linux 服务器上登陆进行远 ...
- 关于remote访问中的flex端配置问题
刚刚开始使用blazeds可能会有个疑问.tomcat服务器是必须配置的吗?如果前台后台分开,怎么开发. 其实服务器不是必须配置的,配置了那个服务器,就会在“附加编译参数”加入这样一句: -servi ...
- main与进程 线程
你起一个CS游戏,这上CS游戏在操作系统中就是一个进程. 但是这个游戏一边在打枪,一边人在走动,一边还有音乐 ,打枪 , 走动 , 音乐 等都是一些线程. 线程不是由进程决定了. 也就是说:你在操作系 ...
- ubuntu后台配置无线网络
一.静态配置: 1.编辑 /etc/network/interfaces: auto loiface lo inet loopback auto wlan0iface wlan0 inet stati ...