博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[JavaScript] 环境与内存
阅读量:6259 次
发布时间:2019-06-22

本文共 2197 字,大约阅读时间需要 7 分钟。

1. 内存分配

1.1 基本类型值和引用类型值

ECMAScript变量包含两种不同数据类型的值:基本类型值和引用类型值。基本类型值保存在栈内存中,而引用类型值保存在堆内存中。

5种基本类型Undefined、Null、Boolean、Number、String,它们的值在内存中分别占有固定大小的空间,因此可以把它们的值保存在栈内存中,也可以提高查询变量的速度,对于它们可以说是按值访问的。

如果是引用类型的值,则必须在堆内存中分配空间。因为它们的值大小不固定,因此不能保存在栈内存中,但内存地址的大小是固定的,所以可以将内存地址保存在栈内存中,再根据地址找到保存在堆中的值,这种查询方式叫做按引用访问。

1.2 动态属性

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

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

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

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

1.3 复制变量值

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

var num1 = 5;var num2 = num1;

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

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

1.4 传递参数

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

使用基本类型值传递参数比较简单,例如:

function add(num) {  num += 10;  return num;}var number = 20;var result = add(number);alert(number); //20alert(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

1.5 检测类型

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

result = variable instanceof constructor

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

2. 执行环境

2.1 环境与作用域

执行环境定义了变量或函数有权访问的其他数据,每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中。这个对象无法访问,但解析器会在后台使用它。

全局执行环境是最外围的一个执行环境,在Web浏览器中,全局执行环境被认为是window对象。某个执行环境中的所有代码执行完毕后,该环境被销毁,保存在其中的所有变量和函数定义也随之销毁。

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

2.2 作用域链的延长

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

1) try-cache语句的catch块。

2) with语句。

2.3 块级作用域

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

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

2.4 变量声明

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

转载地址:http://fuqsa.baihongyu.com/

你可能感兴趣的文章
检查HP服务器硬盘状态脚本
查看>>
Java基础之函数
查看>>
NAT负载均衡_ftp
查看>>
kafka集群搭建
查看>>
Mongodb大数据语法大全
查看>>
Linux的简单SHELL
查看>>
bat清理日志文件
查看>>
python——“破解”私有属性
查看>>
httpclient请求域名自定义域名指向ip
查看>>
安装 MySQL报错 -bash: mysql: command not found
查看>>
RedHat6.4使用CentOS163yum源在线安装及更新软件
查看>>
BUG: soft lockup - CPU#0 stuck for 22s! [kworker/0:2:27076]
查看>>
亿美软通亮相亿邦未来零售大会,斩获智能商业创新奖
查看>>
sed awk 笔记(二)
查看>>
DOCKER 给运行中的容器添加映射端口
查看>>
linux |版权许可GNU和GPL
查看>>
System Center 2012 SP1 之四 配置App Controller
查看>>
第三篇 Python函数(day3)
查看>>
如何轻松快速搭建商城系统?
查看>>
Ansible问题汇总
查看>>