收藏本站腾讯微博新浪微博

经典论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

蓝色理想 最新研发动态 网站开通淘帖功能 - 蓝色理想插件 论坛内容导读一页看论坛 - 给官方提建议

论坛活动及任务 地图和邮件任务 请多用悬赏提问 热夏来袭,选一款蓝色理想的个性T恤吧!

手机上论坛,使用APP获得更好体验 急需前端攻城狮,获得内部推荐机会 论坛开通淘帖功能,收藏终于可以分类了!

搜索
查看: 1402|回复: 0

[病毒] JavaScript的环境与内存

[复制链接]
发表于 2014-5-29 13:49:16 | 显示全部楼层 |阅读模式
使用具备垃圾收集机制语言编写程序,开发人员一般不必操心内存管理的问题。但是,JavaScript在进行内存管理即垃圾收集时面临的问题还是有点与众不同。其中最主要的一个问题,就是分配给Web浏览器的可用内存数量通常要比分配给桌面应用程序的少。确保占有最少的内存可以让页面获得更好的性能,而优化内存占有最佳方式,就是为执行的代码值保存必要的数据。

基本类型值和引用类型值

ECMAScript变量包含两种不同数据类型的值:基本类型值和引用类型值。基本类型值保存在栈内存中,而引用类型值保存在堆内存中。
5种基本类型Undefined、Null、Boolean、Number、String,它们的值在内存中分别占有固定大小的空间,因此可以把它们的值保存在栈内存中,也可以提高查询变量的速度,对于它们可以说是按值访问的。
如果是引用类型的值,则必须在堆内存中分配空间。因为它们的值大小不固定,因此不能保存在栈内存中,但内存地址的大小是固定的,所以可以将内存地址保存在栈内存中,再根据地址找到保存在堆中的值,这种查询方式叫做按引用访问。

动态属性

对于引用类型的值,可以为其添加属性和方法,也可以改变和删除其属性和方法,例如:

var myobj = new Object();
myobj.name = "obj";
alert(myobj.name);

但是不能给基本类型的值添加属性,例如:

var mystr = "string";
mystr.name = "str";
alert(mystr.name); //undefined

复制变量值

如果从一个变量向另一个变量复制基本类型的值,会在栈中创建一个新值,然后把该值复制到为新变量分配的位置上,例如:

var num1 = 5;
var num2 = num1;

如果从一个变量向另一个变量复制引用类型的值,同样会将存储在栈中的值复制一份放到为新变量分配的空间中。但是这个值的副本实际是指向存储在堆中的一个对象的指针,例如:

var myobj1 = new Object();
var myobj2 = myobj1;
myobj1.name = "obj";
alert(myobj2.name); //obj

传递参数

ECMAScript中所有函数参数都是按值传递的。在向参数传递基本类型的值时,被传递的值会被复制给一个局部变量,在向参数传递引用类型的值时,会把这个值在内存中的地址复制给一个局部变量。
使用基本类型值传递参数比较简单,例如:

function add(num) {
  num += 10;
  return num;
}
var number = 20;
var result = add(number);
alert(number); //20
alert(result); //30

如果使用引用类型值则稍复杂,例如:

function setName(obj) {
  obj.name = "obj";
}
var myobj = new Object();
setName(myobj);
alert(myobj.name); //obj

但这并不表明局部作用域中修改的对象会在全局作用域中反映出来,对象仍然是按值(内存地址)传递的,例如:

function setName(obj) {
  obj.name = "obj";
  obj = new Object();
  obj.name = "new obj";
}
var myobj = new Object();
setName(myobj);
alert(myobj.name); //obj

检测类型

typeof操作符可以检测一个变量是哪种基本类型,但在检测引用类型时,总是返回object。通常我们并不是想知道某个值是对象,而是想知道它是什么类型的对象,可以使用instanceof操作符,语法如下:

result = variable instanceof constructor

如果变量是给定引用类型的实例,那么instanceof操作符就会返回true。根据规定,所有引用类型的值都是Object的实例。

环境与作用域

执行环境定义了变量或函数有权访问的其他数据,每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中。这个对象无法访问,但解析器会在后台使用它。全局执行环境是最外围的一个执行环境,在Web浏览器中,全局执行环境被认为是window对象。某个执行环境中的所有代码执行完毕后,该环境被销毁,保存在其中的所有变量和函数定义也随之销毁。

当代码在一个环境中执行时,会创建由变量对象构成的一个作用域链,保证对执行环境有权访问的所有变量和函数的有序访问。全局执行环境是作用域链中的最后一环,标识符解析是沿着作用域链一级级搜索,从作用域链接前端(当前执行环境)开始,直到找到标识符为止。

作用域链的延长

有些语句可以在作用域链的前端临时增加一个变量对象,该变量对象会在代码执行后被移除,即当执行流进入下列任何一个语句时,作用域链就会得到加长:

try-cache语句的catch块。
with语句。

块级作用域

JavaScript没有块级作用域,即花括号封闭的代码块中定义的变量可以在代码块外访问,例如:

if (true) {
  var color = "blue";
}
alert(color);

变量声明

在使用var关键字声明变量时,这个变量将被自动添加到距离最近的可用环境中。如果变量在未经声明的情况下被初始化,那么该变量会被自动添加到全局环境。

本文为Anyforweb技术分享博客,需要了解网站建设及更多web应用相关信息,请访问anyforweb.com。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|小黑屋|Archiver|手机版|blueidea.com ( 湘ICP备12001430号 )  

GMT+8, 2020-10-21 14:58 , Processed in 0.099357 second(s), 7 queries , Gzip On, Memcache On.

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表