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小时 读书: ...
随机推荐
- 2016-2-1 Servlet细节
Servlet的一些细节(韩顺平老师视频讲解)(1)由于客户端是通过URL地址访问web服务器中的资源,所以Servlet程序想要被外界访问,必须把servlet程序映射到一个URL地址上.这个工作在 ...
- 简述JavaScript对象、数组对象与类数组对象
问题引出 在上图给出的文档中,用JavaScript获取那个a标签,要用什么办法呢?相信第一反应一定是使用document.getElementsByTagName('a')[0]来获取.同样的,在使 ...
- [机器学习] Ubuntu 软件源更新(校园网)以及问题总结
最近在折腾Linux,在校园网下怎么能够很好的获取软件很是让我头疼啊~~~ 总结一下吧!!! 首先是校园网的源地址: 清华大学:https://mirrors.tuna.tsinghua.edu.cn ...
- Python学习笔记(1)
从今天开始正式学习python,教程看的是廖雪峰老师的Python 2.7教程.链接在此:http://www.liaoxuefeng.com/wiki/0014316089557264a6b3489 ...
- linux platform设备与驱动
struct platform_driver { int (*probe)(struct platform_device *); int (*remove)(struct platform_devic ...
- tomcat在linux下自启动
Linux下设置tomcat开机自启动 一.以root用户登录系统: 二.进入init.d文件夹 cd /etc/init.d/ 三.创建并打开tomcat文件 vi tomcat 四.tomcat ...
- nodejs的实现原理和搭建服务器(动态)
心得体会 今天是我学习的Node.js的第二天,所谓的node.js其实它是javascript编写的服务器的语言,同时它又是属于后台的框架,是一个开放性的平台. 一.相关理论知识: 我们可以用 ...
- 封装一些常用的js工具函数-不定时更新(希望大家积极留言,反馈bug^_^)
/*华丽------------------------------------------------------------------------------------------------ ...
- 日常关键字:定时关机、该任务映像已损坏或已篡改.(0x80041321)、ChaZD生词同步扇贝
我在床上用chinanet网络慢得简直令人发指,12B/S.是的你没有看错,这是我最常看到的网速.但是我最近发现电脑联网开出一个WiFi,在床上用手机上网时,网速会一点提升,可达到1KB/S(⊙﹏⊙) ...
- 干掉命令行窗口下MySql乱码
晚上重温dos窗口操作mysql的时候,遇到了一个巨蛋疼的问题------>中文验证码 -->_-->,所以找了找资料弄懂了怎么解决乱码问题,,小记一下. 新建一个表 create ...