JavaScript中变量、作用域和内存问题(JavaScript高级程序设计第4章)
一、变量
(1)ECMAScript变量肯能包含两种不同的数据类型的值:基本类型值和引用类型值。基本类型值指的是简单的数据段,引用类型值指那些可能由多个值构成的对象。
(2)基本数据类型是按值访问,可以操作保存在变量中的实际的值;引用类型的值是保存在内存中对象,操作对象时,实际上是在操作对象的引用而不是实际的对象,引用类型的值是按引用访问的。

(3)传递参数。ECMScript中所有的函数的参数都是按值传递的。
function setName(obj){
obj.name = "Nicholas";
obj = new Object(); //理解为新建一个对象,这个对象和参数obj的值不同,即在堆中地址不同,堆中值也不同,不是同一个对象
obj.name = "Greg"; //函数执行完后,新建的obj被销毁。
}
var person = new Object();
setName(person);
alert(person.name); //"Nicholas"
当在函数内部重写obj时,这个变量引用的就是一个局部对象了。而这个局部对象会在函数执行完毕后立即被销毁。
(4)instanceof操作符 如果变量时给定引用类型的实例,那么instanceof操作符始终会返回true;如果使用instanceof操作符检测基本类型的值,则操作符始终返回false;因为基本类型不是对象。
二、执行环境及作用域
(1)执行环境是JavaScript中最为重要的一个概念。执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为。每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中。
全局执行环境是最外围的一个执行环境。在web浏览器中,全局执行环境被认为是window对象。
当代码在一个环境中执行时,会创建变量对象的一个作用域链。作用域链的作用是保证对执行环境有权访问的所有变量和函数的有序访问。作用域链的前端,始终都是当前执行的代码所在环境的变量对象。如果这个环境是函数,则将其活动对象作为变量对象。活动对象在最开始时只包含一个变量,即arguments对象(这个对象在全局环境中是不存在的)。全局执行环境的变量对象始终都是作用域链中的最后一个对象。
(2)没有块级作用域
if(true){
var color = "blue";
}
alert(color); //blue;
for(vari = 0; i < 10;i++){
doSomething(i);
}
alert(i); //10;
对于JavaScript来说,由for语句创建的变量 i 即使在for循环执行结束后,也依旧会存在于循环外部的执行环境中。
三、垃圾收集
(1)JavaScript具有自动垃圾收集机制。这种垃圾收集机制的原理其实很简单:找出那些不再继续使用的变量,然后释放其占用的内存。
JavaScript中最常用的垃圾收集方式是标记清除。垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记。然后,它会去掉环境中的变量以及被环境中的变量引用的变量的标记。而在此之后再被加上标记的变量将被视为准备删除的变量。
另一种不太常见的垃圾收集策略叫做引用计数。
(2)管理内存
JavaScript在进行内存管理及垃圾收集时面临的问题还是有点与众不同。其中最主要的一个问题,就是分配给web浏览器的可用内存数量通常要比分配给桌面应用程序的少。这样做的目的主要是出于安全方面考虑,目的是防止运行JavaScript的网页耗尽全部系统内存而导致系统崩溃。内存限制问题不仅会影响给变量分配内存,同时还会影响调用栈以及在一个线程中能够同时执行的语句数量。
优化内存占用的最佳方式,就是为执行中的代码值保存必要的数据。一旦数据不再有用,最好通过将其值设置为null来释放其引用——这个做法叫做解除引用
。这一做法使用于大多数全局变量和全局对象的属性。
function createPerson(name){
var localPerson = new Object();
localPerdon.name = name;
return localPerson;
}
var globalPerson = createPerson("Nicholas");
//手工解除globalPerson的引用
globalPerson = null;
解除一个值的引用并不意味着自动挥手该值所占用的内存。解除引用的真正作用是让值脱离执行环境,以便垃圾收集器下次运行时将其回收。
JavaScript中变量、作用域和内存问题(JavaScript高级程序设计第4章)的更多相关文章
- 浅谈javascript中变量作用域和内存(2)
1.无块级作用域 javascript没有块级作用域,这会让其他程序员在理解js代码上很痛苦.在其他很多语言,比如C,大括号括起来的代码块都有自己的作用域 举个例子 if(true) { var na ...
- 浅谈javascript中变量作用域和内存(1)
先理解两个概念:基本类型和引用类型的值 1.基本类型和引用类型的值 (1)定义: 基本类型:指简单的数据段,比如按值访问的js五种基本数据类型undefined.null.boolean.number ...
- Javascript中变量作用域
<script type="text/javascript"> var a = 10; var Bar = (function () { console.log(a); ...
- Javascript中变量作用域(2)
多层函数调用取变量时,无论在哪里调用,要到创建此函数的作用域中取值,如果找不到再往上一级,直到全局变量. 外面定义了很多的全局的变量,下面我们来一个个理一下. 定义三个变量a,b,c;将A1函数赋值给 ...
- JavaScript 中变量、作用域和内存问题的学习
这是我学习JavaScript的第二篇文章,之前做过几年的Java开发,发现JavaScript虽然也是面向对象的语言但是确实有很多不同之处.就本篇博客,主要学习总结一下最近学习到的JavaScrip ...
- 第一百零六节,JavaScript变量作用域及内存
JavaScript变量作用域及内存 学习要点: 1.变量及作用域 2.内存问题 JavaScript的变量与其他语言的变量有很大区别.JavaScript变量是松散型的(不强制类型)本质,决定了它只 ...
- javascript的变量作用域--对比js、php和c的for循环
为什么要写这篇文章呢?主要是给自己提个醒,js的水很深,需要小心点儿才能趟过去,更何况自己不是专业人士,那就得更加小心了. 看下面的js代码: <!DOCTYPE html> <ht ...
- [转]深入理解JavaScript的变量作用域
1.JavaScript的作用域链 2.函数体内部,局部变量的优先级比同名的全局变量高. 3.JavaScript没有块级作用域. 4.函数中声明的变量在整个函数中都有定义. 5.未使用var关键字定 ...
- JavaScript中的作用域
很多(JavaScript)开发者都在讨论"作用域",但它是什么?它们在JavaScript中的任何地方!我发现很多年轻的开发者不知道作用域是什么.他们中大多数人可以用jQuery ...
- 深入理解JavaScript的变量作用域(转载Rain Man之作)
在学习JavaScript的变量作用域之前,我们应当明确几点: JavaScript的变量作用域是基于其特有的作用域链的. JavaScript没有块级作用域. 函数中声明的变量在整个函数中都有定义. ...
随机推荐
- Fiddler抓取HTTPS设置
做App测试,用Fiddler进行抓包,以下操作记录如何用手机进行设置使其可以捕捉HTTPS协议. 一.电脑端设置 1.手机和电脑保持统一局域网内 2.配置fiddler允许监听到https 打开Fi ...
- C#局部类型partial在定义实体类Model中的应用
以前一直用继承类的方法,原来还可以这样 //例如:定义一个Person的实体类,用户ID(PersonId),姓名(Name),性别(Sex),年龄(Age),地址(Address),联系方式(Tel ...
- Winform datagridview 基础
======================================================================================== == 重点需要掌握 A ...
- AJPFX总结heap和stack有什么区别?
栈是后进先出的线性表结构,存取速度比堆快.创建对象的时候new一个对象,引用存在栈上具体的内容存在堆上. 栈与堆都是Java用来在RAM中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不 ...
- 【经验总结】OSG 安装配置
对于普通用户推荐直接下载安装包配置.如有特殊需求或想了解编译过程可参考网上文章自己编译后配置.(通常建议使用第一种方法即可) 本人安装经验: 失败:自己系统64位,VS2010 32位,开始自己动手编 ...
- 搭建SSM框架(聚合项目)
parents 父工程 pom base用户权限 jar wms业务 jar app帮助管理 war1. parents的pom.xml文件 1.1 maven servlet3.1.0 1.2 ...
- Java子类与父类方法的隐藏和覆盖
class Base{ int x = 1; static int y = 2; String name(){ return "mother" ...
- ubuntu上部署windows开发的dotnet core程序
目标:完成windows上开发的dotnet core程序部署至linux服务器上(Ubuntu 14.04) windows上开发dotnet core很简单,安装好VS2017,建立相关类型的项目 ...
- axios的简单封装及在组件内使用
/**第一步 * 配置编译环境和线上环境之间的切换 * baseUrl: 域名地址 * routerMode: 路由模式 * imgBaseUrl: 图片所在域名地址 * */ let Host = ...
- liunx防火墙的基本操作
centos7中的使用 CentOS 7.0默认使用的是firewall作为防火墙 查看防火墙状态------->firewall-cmd --state 停止firewall-------&g ...