内存问题是 JavaScript 比较底层的东西,依葫芦画瓢学会了怎么使用变量,但是对于内存的概念依然模糊,今天让我们一起来了解一下内存在这门语言是怎么样的存在。

内存在不同类型的数值面前表现有很大的不同。我们把值赋给一个变量,解析器必须确定这个值是什么类型,先来了解变量的两个类型:

  • 基本类型:简单的数据段:Undefined、Null、Boolean、Number、String,按值访问,可以直接操作实际的值。

  • 引用类型:保存在内存中的对象:Object、Array。。JavaScript 赋值保存着对象的某个变量时,操作的是对象的引用;在为对象添加属性的时候,操作的是实际的对象。

复制基本类型的数据时,计算机会重新分配一个位置给新的变量;但是复制引用类型的数据,计算机只是复制了一个指针,指向原有的对象。所以改变其中一个引用类型数据的属性时,访问另一个引用类型数据的属性能得到一样的结果,比如:

复制基本类型并改变其中一个变量:

let a = 20;
let b = a;
b = 30;
console.log(a) // 20

复制引用类型并改变其中一个变量的属性:

let m = {a:10, b:20};
let n = m;
n.a = 15;
console.log(m.a) // 15

m,n 都指向一个引用类型的对象,所以改变 n 的属性会导致 m 的属性改变。上面表示的是变量之间基本的复制,但是注意:** 在所有函数的参数传递中,都是按值传递的,不是按照引用传递的 **。比如:

function setName(obj){
obj.name = "Nicholas";
obj = new Object();
obj.name = "Greg";
} let person = new Object();
setName(person);
alert(person.name); // "Nicholas"

JS 内存空间分为栈(stack)、堆(heap)、池(一般也会归类为栈中)。其中「栈」存放基本类型变量,遵循后进先出的原则;「堆」存放引用类型,堆存取数据的方式,则与书架与书非常相似,知道名字就能取出来用;池存放常量。

检测一个变量是不是基本类型,用 typeof 操作符就可以搞定,但是这个操作符在遇到对象或者 null 时,返回 Object,我们不知道具体的类型。这时候,用 instanceof 来确认是什么类型的对象。

内存泄漏与回收

不再用到的内存,没有及时释放,就叫做内存泄露。

大多数语言提供自动内存管理,减轻程序员的负担,这被称为“垃圾回收机制”(garbage collector)。原理很简单:找出那些不再继续使用的变量,然后释放其占用的内存。

JavaScript 具有自动垃圾收集机制,不用程序员操太多心。而不同的浏览器可能会采取不同的回收策略,现代浏览器最常用的方式是标记清除,其次是引用计数。

  • 标记清除。垃圾收集器会给内存中的所有变量都添加标记,然后清除一些还会被使用的标记,即凡是环境中还会用到的变量,被其他变量引用的变量。还有标记的变量就会被垃圾收集器删除,完成内存的清除工作。
  • 引用计数。原理也很简单,跟踪每个变量被引用的次数。这里会产生一个棘手的问题,就是遇到 “循环引用” 就没招了。解决的方法是不再使用的对象,我们把它设置成空对象 Null 。看下面的例子:
function(){
let a = new Object();
let b = new Object(); a.oneObject = b;
b.anotherObject = a;
}

上面的代码中,a 和 b 通过各自的属性实现相互引用,两者的被引用次数都是 2 。如果采用标记清楚策略,由于函数执行结束,这两个对象都离开了作用域,都会被清除。但是,采用引用计数策略,a 和 b 都还继续存在,因为他们的引用次数永远不会是 0。此时,只有手动断开引用。

function(){
let a = new Object();
let b = new Object(); a.oneObject = b;
b.anotherObject = a; // 消除循环:
a.oneObject = null
b.anotherObject = null;
}

学习 JavaScript (七) 内存问题的更多相关文章

  1. 前端学习 第七弹: Javascript实现图片的延迟加载

    前端学习 第七弹: Javascript实现图片的延迟加载 为了实现图片进入视野范围才开始加载首先: <img    src="" x-src="/acsascas ...

  2. JavaScript学习系列之内存模型篇

    一个热爱技术的菜鸟...用点滴的积累铸就明日的达人 正文 如果真的想学好一门语言,那么一定要了解它内存模型,本篇文章就带你走进JavaScript的内存模型,由于本人才疏学浅,若有什么表述有误的地方, ...

  3. 一步步学习javascript基础篇(8):细说事件

    终于学到事件了,不知道为何听到“事件”就有一种莫名的兴奋.可能是之前的那些知识点过于枯燥无味吧,说起事件感觉顿时高大上了.今天我们就来好好分析下这个高大上的东西. 可以说,如果没有事件我们的页面就只能 ...

  4. 学习javascript数据结构(二)——链表

    前言 人生总是直向前行走,从不留下什么. 原文地址:学习javascript数据结构(二)--链表 博主博客地址:Damonare的个人博客 正文 链表简介 上一篇博客-学习javascript数据结 ...

  5. 学习javascript数据结构(一)——栈和队列

    前言 只要你不计较得失,人生还有什么不能想法子克服的. 原文地址:学习javascript数据结构(一)--栈和队列 博主博客地址:Damonare的个人博客 几乎所有的编程语言都原生支持数组类型,因 ...

  6. 《如何正确学习JavaScript》读后小结

    在segmentfault上读的一篇学习JavaScript路线的文章,做个小结. 一.简介.数据类型.表达式和操作符 (1)<JavaScript权威指南>前言1-2章&< ...

  7. C语言学习 第七次作业总结

    C语言学习 第七次作业总结 数组可以分为数组和多下标数组(在传统的国内C语言书本中,将其称为二/多维数组). 数组名称 在之前的课程中,大家应该都有印象,对于int a这样的定义,会为变量 a 声明一 ...

  8. 一步步学习javascript基础篇(6):函数表达式之【闭包】

    回顾前面介绍过的三种定义函数方式 1. function sum (num1, num2) { return num1 + num2; }  //函数声明语法定义 2. var sum = funct ...

  9. 一步步学习javascript基础篇(4):面向对象设计之创建对象(工厂、原型和构造函数等模式)

    前面我们介绍了可以通过Object构造函数或对象字面量都可以用来创建单个对象,但是如果需要创建多个对象的话,显然很多冗余代码. 接下来介绍几种模式来创建对象.不过在此之前,我们还是先来了解下 type ...

  10. 一步步学习javascript基础篇(3):Object、Function等引用类型

    我们在<一步步学习javascript基础篇(1):基本概念>中简单的介绍了五种基本数据类型Undefined.Null.Boolean.Number和String.今天我们主要介绍下复杂 ...

随机推荐

  1. Java注解处理器--编译时处理的注解

    1. 一些基本概念 在开始之前,我们需要声明一件重要的事情是:我们不是在讨论在运行时通过反射机制运行处理的注解,而是在讨论在编译时处理的注解.注解处理器是 javac 自带的一个工具,用来在编译时期扫 ...

  2. Django中数据库表的关联与创建(语言:python)

    首先选择选用的数据库,(本人选用django(1.11.8版本)) 在主项目settings中操作如下: DATABASES = { 'default': { 'ENGINE': 'django.db ...

  3. JDK1.8的新特性

    JAVA8新特性 接口改善 现在接口里已经完全可以定义静态方法了. 举一个比较普遍的例子就是在java类库中, 对于一些接口如Foo, 都会有一个有静态方法的工具类Foos 来生成或者配合Foo对象实 ...

  4. C#学习(一):委托和事件

    预备知识 在学习委托和事件之前,我们需要知道的是,很多程序都有一个共同的需求,即当一个特定的程序事件发生时,程序的其他部分可以得到该事件已经发生的通知. 而发布者/订阅者模式可以满足这种需求.简单来说 ...

  5. PAT1107:Social Clusters

    1107. Social Clusters (30) 时间限制 1000 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue When ...

  6. 【转】tomcat logs 目录下各日志文件的含义

    tomcat每次启动时,自动在logs目录下生产以下日志文件,按照日期自动备份   localhost.2016-07-05.txt   //经常用到的文件之一 ,程序异常没有被捕获的时候抛出的地方 ...

  7. Java公开课-04.异常

    一,异常的概念 程序在运行时,发生了我们没有预测的结果,它阻止了程序按照我们预期效果执行 二,怎么保证我们的程序在发生异常以后 ,代码继续执行? 异常处理机制 在程序发生异常以后,还能按照我们事先设定 ...

  8. Git Push:error: Couldn't set refs/remotes/origin/master;error: update_ref failed for ref 'refs/remot

    作者:荒原之梦 原文链接:http://zhaokaifeng.com/?p=543 今天使用Git Push代码时产生错误: Rename from 'XXXX/.git/refs/remotes/ ...

  9. pdf在线加载·

    https://yq.aliyun.com/articles/40197  在线例子是这个

  10. 你不知道的JavaScript--Item12 undefined 与 null

    当讨论JavaScript中的原始数据类型时,大多数人都知道从String.Number到Boolean的基本知识.这些原始类型相当简单,行为符合常识.但是,本文将更多关注独特的原始数据类型Null和 ...