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章--变量、作用域和内存)的更多相关文章

  1. js高程读书笔记(1-3章)

    一.js简介 js是一种专为与网页交互而设计的脚本语言,由以下三个不同的部分组成: 1.ECMAScript,由ECMA-262(它规定了语言的这些组成部分:语法,类型,语句,关键字,保留字,操作符, ...

  2. C++ Primer 读书笔记 第2章 变量和基本类型

    C++ Primer 第二章 变量和基本类型 2.1 基本内置类型 C++定义了一组表示整数.浮点数.单个字符和布尔值的算术类型(arithmetic type),此外还定义了Void类型. 算术类型 ...

  3. C++ primer plus读书笔记——第12章 类和动态内存分配

    第12章 类和动态内存分配 1. 静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域运算符来指出静态成员所属的类.但如果静态成员是整形或枚举型const,则可以在类声明中初始化 ...

  4. JS高程读书笔记-第一、二章-内附在线思维导图和quizlet卡片

    之前在kindle上买了高程,今天又到了纸质的<JavaScript语言精粹>,<高性能JavaScript>,<JavaScipt设计模式>,开始读书之旅啦. 我 ...

  5. 读书笔记 - js高级程序设计 - 第四章 变量 作用域 和 内存问题

      5种基本数据类型 可以直接对值操作 判断引用类型 var result = instanceof Array 执行环境 每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这 ...

  6. 《js高程》笔记总结二(变量,作用域,内存问题)

    理解基本类型和引用类型的值,理解执行环境,理解垃圾收集 基本类型的值和引用类型的值 基本类型:简单的数据段,引用类型:指可能由多个值构成的对象(在将一个值赋值的时候,解析器必须知道这个值是基本类型值还 ...

  7. 《JavaScript高级程序设计》 - 读书笔记 - 第4章 变量、作用域和内存问题

    4.1 基本类型和引用类型的值 JavaScript变量是松散类型的,它只是保存特定值的一个名字而已. ECMAScript变量包含两种数据类型的值:基本类型值和引用类型值.基本类型值指的是简单的数据 ...

  8. javascript高级程序设计第3版——第4章 变量作用域以及内存

  9. 《Linux内核设计与实现》第五周读书笔记——第十一章

    <Linux内核设计与实现>第五周读书笔记——第十一章 20135301张忻 估算学习时间:共2.5小时 读书:2.0 代码:0 作业:0 博客:0.5 实际学习时间:共3.0小时 读书: ...

随机推荐

  1. iOS Swift 3 open

    参考资料:http://stackoverflow.com/questions/38947101/what-is-the-open-keyword-in-swift

  2. 前端性能优化--为什么DOM操作慢?

    作为一个前端,不能不考虑性能问题.对于大多数前端来说,性能优化的方法可能包括以下这些: 减少HTTP请求(合并css.js,雪碧图/base64图片) 压缩(css.js.图片皆可压缩) 样式表放头部 ...

  3. MongoDB数据库安装与连接

  4. .net core Jwt 添加

    Jwt 已经成为跨平台身份验证通用方案,如不了解请关注:https://jwt.io/. 为了和微软其他验证模块有个比较好的衔接,项目中采用了微软开发的jwt组件: System.IdentityMo ...

  5. 理解storm的ACKER机制原理

    一.简介:       storm中有一个很重要的特性: 保证发出的每个tuple都会被完整处理.一个tuple被完全处理的意思是: 这个tuple以及由这个tuple所产生的所有的子tuple都被成 ...

  6. <!DOCTYPE html>很重要

    噩梦开始的源头:之前写html或者jsp页面,从来不注意doctype的声明,也不太明白doctype的作用.直到最近碰到了一个非常奇葩的 bug:某一个页面在IE7和8,Chrome,ff等下正常, ...

  7. Putty部署tomcat

    webserver下是tomcatprojects放置项目源代码webapp下放置项目 1. 输入地址栏 登入进去32 192.168.1.32 端口号22 2.进入projects文件夹 cd pr ...

  8. 深入super,看Python如何解决钻石继承难题 【转】

    原文地址 http://www.cnblogs.com/testview/p/4651198.html 1.   Python的继承以及调用父类成员 python子类调用父类成员有2种方法,分别是普通 ...

  9. 1051. Pop Sequence

    原题连接:https://www.patest.cn/contests/pat-a-practise/1051 题目: Given a stack which can keep M numbers a ...

  10. CentOS 安装 gcc-c++

    由于网络环境的问题,很难在线安装,可以 直接挂载安装盘文件,然后在Pacakage 中进行本地安装