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. C# DataGridView绑定数据源

    第一种: DataSet ds=new DataSet (); ]; 第二种: DataTable dt=new DataTable(); this.dataGridView1.DataSource= ...

  2. POJ3461 KMP 模板题

    最近忙着考研复习,所以刷题少了.. 数据结构昨天重新学习了一下KMP算法,今天自己试着写了写,问题还不少,不过KMP算法总归是理解了,以前看v_JULY_v的博客,一头雾水,现在终于懂了他为什么要在算 ...

  3. BZOJ 2152 & 点分治

    Description: 只是打法法塔前测试一下板子 Code: /*================================= # Created time: 2016-04-20 14:3 ...

  4. CS0103: The name ‘Scripts’ does not exist in the current context解决方法

    转至:http://blchen.com/cs0103-the-name-scripts-does-not-exist-in-the-current-context-solution/ 更新:这个bu ...

  5. 20161022 NOIP模拟赛 解题报告

     好元素 [问题描述] 小A一直认为,如果在一个由N个整数组成的数列{An}中,存在以下情况: Am+An+Ap = Ai (1 <= m, n, p < i <= N ,  m,n ...

  6. CSS 是程序员的画笔

    在未来的所有界面.皮肤,都将使用CSS来表现.包括网页.应用.甚至现实物体的包装等等. 因为CSS实践的理念十分优秀:抽离.分类.统一. CSS将是程序员的画笔. 刚做出来的程序基本都是一个样子.产品 ...

  7. PHP:( && )逻辑与运算符使用说明

    第一次看到以下语句的写法大惑不解 ($mCfg['LockChinaIp']==1 && (int)$_SESSION['AdminUserId']==0 && sub ...

  8. Java Hashtable的实现

    先附源码: package java.util; import java.io.*; /** * This class implements a hash table, which maps keys ...

  9. DoTween 教程

    官方网站:http://dotween.demigiant.com/ 下载地址:http://dotween.demigiant.com/download.php pro版下载地址:http://pa ...

  10. spring的代理模式

    静态代理: 首先定义一个接口,随便写一个方法 定义2个实现接口的方法 (被代理的对象) (代理对象) 需要将接口 定义get set 方法 代理增强的方法 然后实现 输出结果如下: 动态代理(jdk动 ...