一、基本类型和引用类型

ECMAScipt变量可能分为两种数据类型:基本类型和引用类型。

基本类型:指简单的数据段;包括Undefined、Null、Boolean、Number、String;可以操作保存在变量中值(栈内存),所以称为按值访问;不能添加属性。

引用类型:可能由多个值构成的对象;包括Arry、Object等;js不允许直接操作对象的内存(堆内存)空间,所以成为按引用访问;可以动态得添加/改变/删除引用类型值的属性和方法。

1.复制

 1   var a=5;
2 var b=a;
3 console.log(a);//5
4 console.log(b);//5
5 a=3;
6 console.log(a);//3
7 console.log(b);//5
8 var arrA=[1,2,3];
9 var arrB=arrA;
10 console.log(arrA);//[1,2,3]
11 console.log(arrB);//[1,2,3]
12 arrA[0]='x';
13 console.log(arrA);//['x',2,3]
14 console.log(arrB);//['x',2,3]
   上述代码中a、b为基本数据类型,arrA、arrB为引用类型。可以看出首先定义并初始化了变量a为5,再定义变量b,此时打印出来a和b都是5;改变a的值为3,再次打印,a为3,b为5。对于引用类型arrA以及arrB,进行类似的操作,会发现arrA和arrB的值保持一致。继续看如下代码
1   var arrC=[1,2,3];
2 var arrD=arrC;
3 console.log(arrC);//[1,2,3]
4 console.log(arrD);//[1,2,3]
5 arrC=['X','Y','Z'];
6 console.log(arrC);//['X','Y','Z']
7 console.log(arrD);//[1,2,3]

此时引用类型arrC、arrD的值并没有改变。这是因为基本类型是在变量对象上,而引用类型是保存在内存中。基本类型的变量是完全相互独立的,而引用类型变量的复制拷贝的实则上是一个指针,这个指针指向存储在内存中的对象。只要指针是指向改变的对象时,则通过这些指针访问的也会发生改变,如arrA、arrB。而arrC与arrD之所以前后没有保持一致,是因为arrC=['X','Y','Z']这个操作,是将arrC的指针指向了另一个对象,即['X','Y','Z']。而arrD的指针的指向并没有发生改变,仍然指向[1,2,3]。

2.传递参数

函数的参数传递是按值传递的,无论是基础类型还是引用类型。这一点书上说的很详细,可以参考书上P71页。

3.检测类型

typeof用来检测基本数据类型,instanceof用来检测引用类型。因为引用类型的值都是Object的实例,所以instanceof检测引用类型和object构造函数时返回true;反之instanceof检测基本类型时,由于基本类型不是对象,所以始终返回false。

二、执行环境及作用域

Web浏览器中,全局执行环境被认为是window对象,所以所有全局变量和函数都是作为window对象的属性和方法创建的,不过一般省略了window。个人感觉这一小节内容还是比较容易理解的,执行环境就只分为两种:全局和局部。

1.延长作用域链

两种方法:try-catch和with语句。由于witch语句会给性能带来影响,所以以前者为例,catch语句会在作用域链的前端添加一个变量对象A,其中包含的是被抛出错误对象的申明,即在catch语句内部,可以引用对象A的属性或方法。

2.JS语言没有块级作用域

由于访问局部变量不用向上搜索作用域链,所以访问局部变量要比访问全局变量要快。即使快的不明显,但是仍然要尽量避免使用全局变量,防止变量污染。

三、垃圾收集

JS具有自动垃圾收集机制,所需内存的分配以及无用内存的回收完全实现了自动管理。其原理是:垃圾收集器会按照固定的时间间隔周期性地找出那些不再继续使用的变量,然后释放其占用的内存。局部变量在函数执行完毕时会自动被销毁。

1.JS垃圾收集方式有两种:标记清除和引用计数。

前者最常用,简单来讲,垃圾收集器会给存储在内存中的所有变量加上标记,即进入执行环境的变量(占用内存)会被加上一个标记表示不会被清除;当变量要离开环境,执行完毕时,这些变量会再次被标记表示要被清除,此时环境中的变量已经访问不到这些变量。

引用计数是指跟踪记录每个值被引用的次数。当声明一个变量并将一个引用类型赋值给该变量时,其引用次数为1,如果同一个值又被赋给另一个变量,则该值的引用次数家1;相反,如果包含对这个值引用的变量又取到另外一个值,则引用次数减1.当内存中值的引用次数为0时,其占用的内存空间会被回收。通俗来讲,引用次数就是指向内存对象的指针的个数。可以类比前面的arrC和arrD,如下图:

 1   var arrC=[1,2,3];
2 var arrD=arrC;
3 console.log(arrC);//[1,2,3]
4 console.log(arrD);//[1,2,3]
5 arrC=['X','Y','Z'];
6 console.log(arrC);//['X','Y','Z']
7 console.log(arrD);//[1,2,3]

首先内存中的值为[1,2,3],当声明arrC并将值[1,2,3]赋给arrC时,值的引用次数为1,即arrC的指针指向它。当将arrC的值赋给arrD时,值[1,2,3]的引用次数+1为2,此时arrC、arrD的指针都指向值[1,2,3]。接下来,将值['X','Y','Z']赋给arrC时,arrC的指针不再指向值[1,2,3],而是指向值['X','Y','Z'],此时arrD依旧指向值[1,2,3]。值[1,2,3]的引用次数减1为1。引用计数最大的弊端就是循环引用,即两个对象都包含指向对方的引用。

2.性能问题

垃圾收集器是周期运行的,时间间隔的确定会影响浏览器的性能。

3.管理内存

解除引用:将数据的值置为null,适用于大多数全局变量和全局对象的属性,其作用是让值脱离执行环境,以便垃圾收集器下次运行时将其回收。

第4章 变量、作用域和内存---JS红宝书书摘系列笔记的更多相关文章

  1. 第5章 引用类型---JS红宝书书摘系列笔记

    在ECMAScript中,引用类型是一种数据结构,用于将数据和功能组织在一起,描述的是一类对象所具有的属性和方法.而对象是某个特定引用类型的实例. 一.Object类型 可以通过Object构造函数创 ...

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

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

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

  4. JS红宝书笔记——第一章 JavaScript简介

    1.JavaScript简史 Netscape公司决定开发一种客户端语言用来处理浏览器端简单的表单验证. Netscape公司派布兰登·艾奇(BrendanEich)为计划于1995年2月发布的Net ...

  5. js红宝书学习笔记(一)引用类型

    一.引用类型 ECMAScript中,引用类型是一种数据结构称之为对象定义,,引用对象不同于传统面向对象语言所支持的类和接口等基本结构 创建Object 实例的两种方式: new操作符跟Object构 ...

  6. 第一百零六节,JavaScript变量作用域及内存

    JavaScript变量作用域及内存 学习要点: 1.变量及作用域 2.内存问题 JavaScript的变量与其他语言的变量有很大区别.JavaScript变量是松散型的(不强制类型)本质,决定了它只 ...

  7. [转] VS2015中跑OpenGL红宝书第八版的第一章示例代码,运行

    Ori Article Link OpenGL的东西快忘光了,把角落的第八版红宝书拿出来复习一下 从书中的地址下了个示例代码结果新系统(Win10+VS2015)各种跑不起来,懊恼之后在网上疯狂搜索资 ...

  8. js 变量 作用域及内存

    由于Javascript是松散型的,所以其变量只是在特定时间用于保存特定值的一个名字而已,并不存在某个变量必须保存某种类型的值的规则,变量的值以及其数据类型都可以在脚本的声明周期内改变 一.基本类型与 ...

  9. js基础之--变量 作用域和内存问题

    基本类型:Undefind Null Boolean Number String 引用类型: 对象 在操作对象时,实际上实在操作对象的引用而不是实际的对象.为此,引用类型的值是按引用访问的. 从一个变 ...

随机推荐

  1. C++ 两款静态检查工具

    pclint(收费) http://www.gimpel.com/html/pcl.htmpc-lint是资格最老,最强力的代码检查工具,但是是收费软件,并且配置起来有一点点麻烦. ccpchecke ...

  2. Array 对象

    Array的对象用于在单个的变量中存储多个值. constructor 返回对创建此对象的数组函数的引用. demo: let arr=[];  arr.constructor==Array let ...

  3. centos7升级最新内核

    由于最近在测试ceph 的straw2算法,但是要使用straw2需要最新为4.1.0的内核,因此决定将虚机内核升级最新4.11.4. 步骤1.检查本机内核版本 #uname -sr 3.10.0-5 ...

  4. socket辅助类

    using System; using System.Collections; using System.Net; using System.Net.Sockets; using System.Tex ...

  5. Beyond Compare 简体版+注册码

    Beyond Compare 3.3.4.14431 官方简体版+注册码 查阅全文 ›

  6. 1.9 Hive常见属性配置

    一.Hive数据仓库位置配置 1. # Hive数据仓库位置配置: 默认位置(hive根目录): /user/hive/warehouse 注意事项: *在仓库目录下,没有对默认的数据库default ...

  7. 我所理解的Restful API最佳实践

    一直在公司负责API数据接口的开发,期间也遇到了不小的坑,本篇博客算是做一个小小的记录. 1. 不要纠结于无意义的规范    在开始本文之前,我想先说这么一句:RESTful 真的很好,但它只是一种软 ...

  8. 4-1逻辑与运算符介绍 & 4-2逻辑或运算符介绍

    后面括号内的(n++)不运算了. 4-2逻辑或运算符介绍

  9. C#基础:对委托的简单理解

    在编程过程中,我们习惯把数据作为参数传递给方法(例:int a=int.Parse(“20”);).是否能将一个方法传递给另一个方法呢?是不是听起来有点奇怪!!! 线程大家应该熟悉吧,在计算机中并行运 ...

  10. 不能支持C++11的特性~,升级到4.8.2

    一.简易安装 操作环境 CentOS6.5 64bit,原版本4.4.7,不能支持C++11的特性~,希望升级到4.8.2 不能通过yum的方法升级,需要自己手动下载安装包并编译 1.1 获取安装包并 ...