一、背景

var a = 20;

var b = 'abc';

var c = true;

var d = { m: 20 }

因为JavaScript具有自动垃圾回收机制,所以对于前端开发来说,内存空间并不是一个经常被提及的概念,很容易被大家忽视。特别是很多不是计算机专业的朋友在进入到前端之后,会对内存空间的认知比较模糊,甚至有些人干脆就是一无所知.

当然也包括我自己。在很长一段时间里认为内存空间的概念在JS的学习中并不是那么重要。可是后我当我回过头来重新整理JS基础时,发现由于对它们的模糊认知,导致了很多东西我都理解得并不明白。比如最基本的引用数据类型和引用传递到底是怎么回事儿?比如浅复制与深复制有什么不同?还有闭包,原型等等.

因此后来我才渐渐明白,想要对JS的理解更加深刻,就必须对内存空间有一个清晰的认知.


二、栈与堆

与c++类似,javaScipt中的内存也分为栈区和堆区,它们存储数据的机制不同,导致存储数据的类型也不同,栈区主要存储简单数据类型,堆区主要存储引用数据类型.

首先我们简单了解下栈的存取方式,这里我们可以通过类比乒乓球盒子来分析。如下图:

这种乒乓球的存放方式与栈中存取数据的方式如出一辙。处于盒子中最顶层的乒乓球5,它一定是最后被放进去,但可以最先被使用。而我们想要使用底层的乒乓球1,就必须将上面的4个乒乓球取出来,让乒乓球1处于盒子顶层。这就是栈空间先进后出,后进先出的特点。图中已经详细的表明了栈空间的存储原理。

堆存取数据的方式,则与书架与书非常相似。书虽然也整齐的存放在书架上,但是我们只要知道书的名字,我们就可以很方便的取出我们想要的书,而不用像从乒乓球盒子里取乒乓一样,非得将上面的所有乒乓球拿出来才能取到中间的某一个乒乓球。好比在JSON格式的数据中,我们存储的key-value是可以无序的,因为顺序的不同并不影响我们的使用,我们只需要关心书的名字。

三、复杂数据类型与基本数据类型

基础数据类型都是一些简单的数据段,JavaScript中有5中基础数据类型,分别是Undefined、Null、Boolean、Number、String。基础数据类型都是按值访问,因为我们可以直接操作保存在变量中的实际的值。复杂数据类型 包括数组,对象等.

四、引用数据类型与堆内存

与其他语言不同,JS的引用数据类型,比如数组Array,它们值的大小是不固定的。引用数据类型的值是保存在堆内存中的对象。JavaScript不允许直接访问堆内存中的位置,因此我们不能直接操作对象的堆内存空间。在操作对象时,实际上是在操作对象的引用而不是实际的对象。因此,引用类型的值都是按引用访问的。这里的引用,我们可以粗浅地理解为保存在变量对象中的一个地址,该地址与堆内存的实际值相关联。

为了更好的搞懂变量对象与堆内存,我们可以结合以下例子与图解进行理解.

var b = { m: 20 }; // 变量b存在栈中,对应的值就是一个索引指向对象{m: 20},{m:20}作为对象存在于堆内存中.

因此当我们要访问堆内存中的引用数据类型时,实际上我们首先是从变量对象中获取了该对象的地址引用(或者地址指针),然后再从堆内存中取得我们需要的数据。

理解了JS的内存空间,我们就可以借助内存空间的特性来验证一下引用类型的一些特点了。

在前端面试中我们常常会遇到这样一个类似的题目

// demo01.js

var a = 20;

var b = a;

b = 30;

// 这时a的值是多少?

// demo02.js

var m = { a: 10, b: 20 }

var n = m;

n.a = 15;

// 这时m.a的值是多少

在变量对象中的数据发生复制行为时,系统会自动为新的变量分配一个新值。var b = a执行之后,a与b虽然值都等于20,但是他们其实已经是相互独立互不影响的值了。具体如图。所以我们修改了b的值以后,a的值并不会发生变化。

demo01图解

在demo02中,我们通过var n = m执行一次复制引用类型的操作。引用类型的复制同样也会为新的变量自动分配一个新的值保存在变量对象中,但不同的是,这个新的值,仅仅只是引用类型的一个地址指针。当地址指针相同时,尽管他们相互独立,但是在变量对象中访问到的具体对象实际上是同一个。如图所示

因此当我改变n时,m也发生了变化。这就是引用类型的特性。

通过内存的角度来理解,是不是感觉要轻松很多。除此之外,我们还可以以此为基础,一步一步的理解JavaScript的执行上下文,作用域链,闭包,原型链等重要概念。

关于JavaScript的内存机制的更多相关文章

  1. JavaScript 内存机制

    简介 每种编程语言都有它的内存管理机制,比如简单的C有低级的内存管理基元,像malloc(),free().同样我们在学习JavaScript的时候,很有必要了解JavaScript的内存管理机制. ...

  2. javascript的垃圾收集机制

    × 目录 [1]原理 [2]标记清除 [3]引用计数[4]性能问题[5]内存管理 前面的话 javascript具有自动垃圾收集机制,执行环境会负责管理代码执行过程中使用的内存.在编写javascri ...

  3. javascript js 内存泄露

    JavaScript 内存泄露 1.什么是闭包.以及闭包所涉及的作用域链这里就不说了. 2.JavaScript垃圾回收机制 JavaScript不需要手动地释放内存,它使用一种自动垃圾回收机制(ga ...

  4. JavaScript 垃圾回收机制分析

    同C# .Java一样可以手工调用垃圾回收程序,但是由于其消耗大量资源,而且手工调用的不会比浏览器判断的准确,所以不推荐手工调用垃圾回收.   最近精力主要用在了Web 开发上,读了一下<Jav ...

  5. 详细分析 javascript 的内存分配

    JavaScript语言是一门优秀的脚本语言.其中包含脚本语言的灵活性外还拥有许多高级语言的特性.例如充许构建和实例化一个对象,垃圾回 收机制(GC:Garbage Collecation).通常我们 ...

  6. JavaScript 是如何工作的:JavaScript 的内存模型

    摘要: 从内存角度理解 let 和 const 的意义. 原文:JavaScript 是如何工作的:JavaScript 的内存模型 作者:前端小智 Fundebug经授权转载,版权归原作者所有. 这 ...

  7. Javascript IE 内存释放

    一个内存释放的实例 <SCRIPT LANGUAGE="JavaScript"><!--strTest = "1";for ( var i = ...

  8. 浅谈 JavaScript 垃圾回收机制

    github 获取更多资源 https://github.com/ChenMingK/WebKnowledges-Notes 在线阅读:https://www.kancloud.cn/chenmk/w ...

  9. JavaScript的内存模型

    引言 在我们的前端日常工作中,无时无刻不在进行着变量的声明和赋值,你是否也曾碰到过变量声明报错或变量被污染的问题,如果你跟笔者一样碰到过,那么我们应该暂时停下来好好思考问题发生的原因以及如何采取相应的 ...

随机推荐

  1. 使用xpath爬取猫眼电影排行榜

    最近在学习xpath,在网上找资料的时候,发现一个新手经常拿来练手的项目,爬取猫眼电影前一百名排行的信息,很多都是跟崔庆才的很雷同,基本照抄.这里就用xpath自己写了一个程序,同样也是爬取猫眼电影, ...

  2. eclipses配置tomcat

    1,项目右键属性,设置为1.8,与jdk相对应 2,自动发布,tomcat 3,使用自己的tomcat 4,

  3. 访问接口错误,com.netflix.client.ClientException: Load balancer does not have available server for client: panfeng-item-service

    com.netflix.client.ClientException: Load balancer does not have available server for client: panfeng ...

  4. 14Filter&Listener

    1.Filter:过滤器 1.1 概念 生活中的过滤器:净水器,空气净化器,土匪. web中的过滤器:当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能. 过滤器的作用: 一般用于完成 ...

  5. java8学习之Collector同一性与结合性分析

    继续沿着上一次[http://www.cnblogs.com/webor2006/p/8311074.html]Collector接口的javadoc进行阅读,在继续阅读之前,其中有个比较难理解的地方 ...

  6. 高性能mysql 第7章 mysql高级特性之分区表

    分区表: 分区表是一个独立的逻辑表,底层通过多个物理表实现. mysql实现分区表的方式是对底层表的封装.这意味着没有全局索引,索引是建立在底层的每个表上的(跟ORACLE不一样). 用到分区表的几种 ...

  7. 本地安装sass出错问题解析

    2016年3月23日个人博客文章--迁移到segmentfault 安装sass ruby安装因为sass依赖于ruby环境,所以装sass之前先确认装了ruby.先导官网下载个ruby 在安装的时候 ...

  8. 2019ICPC沈阳网络赛-D-Fish eating fruit(树上DP, 换根, 点分治)

    链接: https://nanti.jisuanke.com/t/41403 题意: State Z is a underwater kingdom of the Atlantic Ocean. Th ...

  9. 网络编程简介(OSI七层协议,TCP协议原理,三次握手与四次挥手)

    目录 网络编程 软件开发架构 C/S架构 B/S架构 网络编程的发展史 互联网协议 1.物理连接层 2.数据链路层 3.网络层 4.传输层 5.应用层 三次握手四次挥手 三次握手建链接 数据传输 四次 ...

  10. 树莓派GPIO接口

    一.GPIO模式 GPIO分为板上模式和BCM模式 板上模式即为平时百度谷歌搜到的图,按顺序1-40排列(1B是26引脚) BCM模式为CPU分的,在图上一般会单独标记 二.引脚分类 1.电源:3.3 ...