内存问题是 JavaScript 比较底层的东西,依葫芦画瓢学会了怎么使用变量,可是对于内存的概念依然模糊,今天让咱们一块儿来了解一下内存在这门语言是怎么样的存在。前端
内存在不一样类型的数值面前表现有很大的不一样。咱们把值赋给一个变量,解析器必须肯定这个值是什么类型,先来了解变量的两个类型:程序员
基本类型:简单的数据段:Undefined、Null、Boolean、Number、String,按值访问,能够直接操做实际的值。算法
引用类型:保存在内存中的对象:Object、Array。。JavaScript 赋值保存着对象的某个变量时,操做的是对象的引用;在为对象添加属性的时候,操做的是实际的对象。浏览器
复制基本类型的数据时,计算机会从新分配一个位置给新的变量;可是复制引用类型的数据,计算机只是复制了一个指针,指向原有的对象。因此改变其中一个引用类型数据的属性时,访问另外一个引用类型数据的属性能获得同样的结果,好比:bash
复制基本类型并改变其中一个变量:微信
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 具备自动垃圾收集机制,不用程序员操太多心。而不一样的浏览器可能会采起不一样的回收策略,现代浏览器最经常使用的方式是标记清除,其次是引用计数。
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;
}
复制代码
欢迎你们关注微信公众号:** 可视化技术( visteacher )**
不只有前端和可视化,还有算法、源码分析、书籍相送
我的网站:blog.kurryluo.com
各个分享平台的 KurryLuo 都是在下。
用心学习,认真生活,努力工做!