学习 JavaScript (七) 内存问题
内存问题是 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 (七) 内存问题的更多相关文章
- 前端学习 第七弹: Javascript实现图片的延迟加载
前端学习 第七弹: Javascript实现图片的延迟加载 为了实现图片进入视野范围才开始加载首先: <img src="" x-src="/acsascas ...
- JavaScript学习系列之内存模型篇
一个热爱技术的菜鸟...用点滴的积累铸就明日的达人 正文 如果真的想学好一门语言,那么一定要了解它内存模型,本篇文章就带你走进JavaScript的内存模型,由于本人才疏学浅,若有什么表述有误的地方, ...
- 一步步学习javascript基础篇(8):细说事件
终于学到事件了,不知道为何听到“事件”就有一种莫名的兴奋.可能是之前的那些知识点过于枯燥无味吧,说起事件感觉顿时高大上了.今天我们就来好好分析下这个高大上的东西. 可以说,如果没有事件我们的页面就只能 ...
- 学习javascript数据结构(二)——链表
前言 人生总是直向前行走,从不留下什么. 原文地址:学习javascript数据结构(二)--链表 博主博客地址:Damonare的个人博客 正文 链表简介 上一篇博客-学习javascript数据结 ...
- 学习javascript数据结构(一)——栈和队列
前言 只要你不计较得失,人生还有什么不能想法子克服的. 原文地址:学习javascript数据结构(一)--栈和队列 博主博客地址:Damonare的个人博客 几乎所有的编程语言都原生支持数组类型,因 ...
- 《如何正确学习JavaScript》读后小结
在segmentfault上读的一篇学习JavaScript路线的文章,做个小结. 一.简介.数据类型.表达式和操作符 (1)<JavaScript权威指南>前言1-2章&< ...
- C语言学习 第七次作业总结
C语言学习 第七次作业总结 数组可以分为数组和多下标数组(在传统的国内C语言书本中,将其称为二/多维数组). 数组名称 在之前的课程中,大家应该都有印象,对于int a这样的定义,会为变量 a 声明一 ...
- 一步步学习javascript基础篇(6):函数表达式之【闭包】
回顾前面介绍过的三种定义函数方式 1. function sum (num1, num2) { return num1 + num2; } //函数声明语法定义 2. var sum = funct ...
- 一步步学习javascript基础篇(4):面向对象设计之创建对象(工厂、原型和构造函数等模式)
前面我们介绍了可以通过Object构造函数或对象字面量都可以用来创建单个对象,但是如果需要创建多个对象的话,显然很多冗余代码. 接下来介绍几种模式来创建对象.不过在此之前,我们还是先来了解下 type ...
- 一步步学习javascript基础篇(3):Object、Function等引用类型
我们在<一步步学习javascript基础篇(1):基本概念>中简单的介绍了五种基本数据类型Undefined.Null.Boolean.Number和String.今天我们主要介绍下复杂 ...
随机推荐
- 分享一下 常用的转换方法(例如:数字转金钱,文本与html互转等)
public sealed class SAFCFormater { /// <summary> /// 文本格式到HTML /// </summary> /// <pa ...
- Python微信公众号开发
最近老大叫我学习开发微信,试着玩了下.网上查了下文档.有点过时. 简单步骤: 1)申请服务器并完成环境配置 去腾讯云购买云服务器.当然你也可以购买其他产品,比如阿里云.因为我是学生,有优惠110一年. ...
- 在线引用js资源积累
[jQuery]https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js[Vue]https://cdnjs.cloudfla ...
- TCP连接的建立与释放(三次握手与四次挥手)
TCP连接的建立与释放(三次握手与四次挥手) TCP是面向连接的运输层协议,它提供可靠交付的.全双工的.面向字节流的点对点服务.HTTP协议便是基于TCP协议实现的.(虽然作为应用层协议,HTTP协议 ...
- Spring Boot实战笔记(四)-- Spring常用配置(事件Application Event)
一.事件(Application Event) Spring的事件为Bean和Bean之间的消息通信提供了支持.当一个Bean处理完一个任务之后,希望另一个Bean知道并能做相应的处理,这时我们就需要 ...
- CXF整合spring
近公司需要弄webservics,还说不用框架整合(提倡使用hessian,他们既然说与操作系统有兼容问题,由于人员单薄,不得不屈服,哎),我想了老半天没弄明白他说的不用框架整合spring,尝试过直 ...
- 深夜学算法之SkipList:让链表飞
1. 前言 上次写Python操作LevelDB时提到过,有机会要实现下SkipList.摘录下wiki介绍: 跳跃列表是一种随机化数据结构,基于并联的链表,其效率可比拟二叉查找树. 我们知道对于有序 ...
- Libevent教程001: 简介与配置
本文内容大致翻译自 libevent-book, 但不是照本翻译. 成文时, libevent最新的稳定版为 2.1.8 stable. 即本文如无特殊说明, 所有描述均以 2.1.8 stable ...
- 纯CSS打造进度条
进度条效果如下: CSS部分 body { background-color: white; } .progress-bar { display: flex; flex-direction: row; ...
- 深入js隐式类型转换
前言 相信刚开始了解js的时候,都会遇到 2 =='2',但是 1+'2' == '1'+'2'为false的情况,这时候应该会是一脸懵逼的状态,不得不感慨js弱类型的灵活让人发指,隐式类型转换就是这 ...