js高程读书笔记(第4章--变量、作用域和内存)
JavaScript变量松散类型的本质,决定了它只是在特定时间用于保存特定值的一个名字而已。由于不存在定义某个变量必须要保存何总数据类型值的规则,变量的值及其数据类型可以在脚本的生命周期内改变。
1.基本类型和引用类型的值
ECMAScript可能有两种不同数据类型的值:基本类型值和引用类型值。基本类型值指的是那些保存在栈内存中的简单数据段,即这种值完全保存在内存中的一个位置(基本数据类型有5种:undefined,null,boolean,number和string)。而引用类型值则是指那些保存在堆内存中的对象(变量中保存的实际上是一个指针,指向内存中的另一个位置)
五种基本类型的在内存中分别有固定大小的空间,因此可以把他们的值保存在栈内存中(这样也可以提高查询变量的速度),保存基本类型值的变量是按值访问。如果赋给变量的是一个引用类型的值,则必须在堆内存中为这个值分配空间。这种值的大小不固定,因此不能把他们保存到栈内存中。但内存地址的大小是固定的,因此可以将内存地址保存在栈内存中。查询引用类型的变量时将按引用访问(首先从栈中读取内存地址)
1.1动态属性
基本类型值和引用类型值的定义是类似的:创建一个变量并给该变量赋值。但是,当这个值保存到变量中以后,对不同类型值可以执行的操作则不同,对于引用类型的值,我们可以为其添加属性和方法,也可以改变和删除其属性和方法。不过不能给基本类型的值添加属性。
1.2复制变量值
除了保存的方式不同之外,在从一个变量向另一个变量复制基本类型值和引用类型值时也存在不同。基本类型值的复制过程中,会在栈中创建一个新值,然后把该值复制到新变量分配的位置上。
如:
var num1=5;
var num2=num1;
num2与num1值都是5,不过这两个值是独立的。

而在引用类型中,复制会将存储在栈中的值复制一份放到新的变量分配空间中,不过这个值的副本实际上是一个指针,这个指针指向存储在堆中的一个对象,复制操作结束后,这两个变量实际上将引用同一个对象。
如:
var obj1=new object();
var obj2=obj1;
obj1.name="ni";
alert(obj2.name);//"ni"
obj1和obj2指向的是同一个对象

1.3传递参数
ECMAScript中所有函数的参数都是按值传递的。
1.4检测类型
var s="ni";
var b=true;
var i=22;
var u;
var n=null;
var o=new Object();
使用typeof操作符输出的结果为:
alert(typeof s);//string
alert(typeof b);//boolean
alert(typeof i);//number
alert(typeof u);//undefined
alert(typeof n);//object
alert(typeof o);//object
在检测引用类型时,如果想知道它是什么类型的对象。就要用到instanceof操作符(书上的例子感觉没用)
2.执行环境及作用域
全局执行环境时最外围的一个执行环境,它被认为是window对象。因此所有全局变量和函数都是作为window对象的属性和方法创建的。某个执行环境中的所有代码执行完毕后,该环境被销毁,保存在其中的所有变量和函数定义也随之销毁(全局执行环境直到应用程序退出--例如关闭网页或浏览器时才会被销毁)
当代码在一个环境中执行时,会创建变量对象的一个作用域链。作用域链的用途是保证对执行环境有权访问的所有变量和函数的有序访问。
如:
var color="blue";
function changeColor(){
var anotherColor="red";
function swapColor(){
var tempColor=anotherColor;
anotherColor=color;
color=tempColor;
}
}
它们的关系可用下图表示

对于例子中的swapColor而言,其作用域中包含3个对象:swapColor()的变量对象,changeColor()的变量对象和全局变量对象。swapColor的局部环境开始时会先在自己的变量对象中搜索变量和函数名,搜不到就再搜索上一级作用域链。但上级的作用域链不能搜索下级的作用域链。
2.1延长作用域链
当执行流进入下列任何一个语句时,作用域链就会得到加长:
①try-catch语句的catch块;
②with语句。
这两个语句都会在作用域链的前端添加一个变量对象。对with语句来说,其变量对象中包含着指定对象的所有属性和方法所作的变量声明,对catch语句来说,其变量对象中包含的是被抛出的错误对象的声明。这些对象都是只读的,因此在with和catch语句中声明的比那辆都会被添加到所在执行换将的变量对象中。(没用到过)
2.2没有块级作用域
在if语句中:
if(true){
var color="blue";
}
alert(color);//"blue"
可以看到color变量是在if语句中定义的,在c、c++或java中,color会在if执行完毕后被销毁。不过在javascript中,if语句中的变量声明会将变量添加到当前的执行环境(在这里是全局环境)中,for语句也有这一差异。
2.2.1声明变量
在使用var关键字声明变量时,这个变量将自动添加到距离最近的可用环境中。看个例子:

注:不建议不声明就直接初始化变量
2.2.2查询标识符

2.3垃圾收集
2.3.1标记清除
javascript中最常用的垃圾收集方式是标记清除。当变量进入环境(如在函数中声明一个变量)时,就将这个变量标记为”进入环境“,而当变量离开环境时,则将其标记为”离开环境“。可以使用任何方式来标记变流量。如可以通过翻转某个特殊的位来记录一个变量何时进入环境,或者使用一个”进入环境“的变量列表及一个”离开环境“的变量列表来跟踪哪个变量发生了变化。
2.3.2引用计数
另一种不太常见的垃圾收集策略叫引用计数。引用计数的含义是跟踪记录每个值被引用的次数。
2.3.3性能问题(不太懂)
2.3.4管理内存(貌似就是将一个值的引用赋值为null,手工解除某个对象的引用,这并不意味着自动回收该值所占用的内存,解除引用的真正作用是让值脱离执行环境,以便垃圾收集器下次运行时将其回收)
js高程读书笔记(第4章--变量、作用域和内存)的更多相关文章
- js高程读书笔记(1-3章)
一.js简介 js是一种专为与网页交互而设计的脚本语言,由以下三个不同的部分组成: 1.ECMAScript,由ECMA-262(它规定了语言的这些组成部分:语法,类型,语句,关键字,保留字,操作符, ...
- C++ Primer 读书笔记 第2章 变量和基本类型
C++ Primer 第二章 变量和基本类型 2.1 基本内置类型 C++定义了一组表示整数.浮点数.单个字符和布尔值的算术类型(arithmetic type),此外还定义了Void类型. 算术类型 ...
- C++ primer plus读书笔记——第12章 类和动态内存分配
第12章 类和动态内存分配 1. 静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域运算符来指出静态成员所属的类.但如果静态成员是整形或枚举型const,则可以在类声明中初始化 ...
- JS高程读书笔记-第一、二章-内附在线思维导图和quizlet卡片
之前在kindle上买了高程,今天又到了纸质的<JavaScript语言精粹>,<高性能JavaScript>,<JavaScipt设计模式>,开始读书之旅啦. 我 ...
- 读书笔记 - js高级程序设计 - 第四章 变量 作用域 和 内存问题
5种基本数据类型 可以直接对值操作 判断引用类型 var result = instanceof Array 执行环境 每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这 ...
- 《js高程》笔记总结二(变量,作用域,内存问题)
理解基本类型和引用类型的值,理解执行环境,理解垃圾收集 基本类型的值和引用类型的值 基本类型:简单的数据段,引用类型:指可能由多个值构成的对象(在将一个值赋值的时候,解析器必须知道这个值是基本类型值还 ...
- 《JavaScript高级程序设计》 - 读书笔记 - 第4章 变量、作用域和内存问题
4.1 基本类型和引用类型的值 JavaScript变量是松散类型的,它只是保存特定值的一个名字而已. ECMAScript变量包含两种数据类型的值:基本类型值和引用类型值.基本类型值指的是简单的数据 ...
- javascript高级程序设计第3版——第4章 变量作用域以及内存
- 《Linux内核设计与实现》第五周读书笔记——第十一章
<Linux内核设计与实现>第五周读书笔记——第十一章 20135301张忻 估算学习时间:共2.5小时 读书:2.0 代码:0 作业:0 博客:0.5 实际学习时间:共3.0小时 读书: ...
随机推荐
- ssh密钥私钥不能登陆问题处理
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: UNPROTECTED PRIVATE KEY FILE! ...
- bootstrap内置网格式布局系统:
bootstrap分为12栏,若想要一个元素占用一定的栏数的宽度,可以在这个元素上用一个特定的类,就比如说span1.span2....类. 定义的布局: 定义page-header类,在这个类当中为 ...
- 更改机器名后,打开TFS提示工作区错误的处理
1,打开vs下的"开发人员命令提示"2,按下面格式输入命令:tf workspaces 查看, 假设显示如下: C:\Program Files (x86)\Microsoft V ...
- javascript 执行上下文的理解
首先,为什么某些函数以及变量在没有被声明以前就可以被使用,javascript引擎内部在执行代码以前到底做了些什么?这里,想信大家都会想到,变量声明提前这个概念: 但是,以下我要讲的是,声明提前的这个 ...
- sqlmap http头注入的一个技巧
sqlmap.py -u "url" --host * --thread=1 --batch -v 1 --delay=0.7 --dbms mysql --current-d ...
- sql编程(四)触发器
触发器:一种特殊的存储过程,和制定的表相关,而对于一个表进行的数据操作时自动的触发执行类似winform 事件创建语法:create trigger 触发器的名称on 表名 for insert | ...
- ListView.setAdapter(adapter);空指针异常的解决的总结
报空指针异常一般的情况: 1,没有找到布局文件的ID 检验是不是id重复或者写错了 2.控件没有实例化 3.没有找到布局文件的id,要看看是不是加载了布局了,必须加载了对应的布局才能找到对应布局下的 ...
- Third Day(上班第四天):Android开发环境配置问题相关
换公司新电脑了,重新安装Android开发环境,并配置,具体流程如下:1.百度JDK,访问Oracle官网:http://www.oracle.com/technetwork/java/javase/ ...
- python字符串的使用
之前在网上看了关于python最基础的一些教程,看着都通俗易懂,但是在写的过程中却感觉还是很生涩.关于字符串的使用还是应该多写多练!如何将“teacher_id = 123 #老师ID”转换成字典或者 ...
- Redis 集群的合纵与连横
之前一篇写了关于 Redis 的性能,这篇就写写我认为比性能更重要的扩展性方面的主题. 如果再给我一次回到好几年前的机会,对于使用 Redis 我一开始就要好好考虑将来的扩展问题.就像我们做数据库分库 ...