接下来本文章所属的章节为:JavaScript性能优化,性能优化总是在工作中被提及,本文将会从头开始阐述JavaScript的大多数性能优化方式
注意:
- 性能优化是必要的
- 哪些内容可以被看作是性能优化
- 前端的性能优化是无处不在的
而我们这个阶段探讨的则是:JavaScript语言层面的性能优化。
JavaScript内存管理
首先:内存为什么需要管理?
看一段代码:
<script>
function fn() {
arrList = [];
arrList[100000] = "cny is Coder";
}
fn();
</script>
他在浏览器中运行的时候内存是直线上升的
这就是一个内存泄漏
所以说:在写代码的时候,不够了解内存管理的机制,就会容易编写出一些不容易察觉的内存问题代码,可能就会带来一些意想不到的bug
内存管理介绍
- 内存:由可读写单元组成,表示一片可以操作的空间
- 管理:人为的去操作一片空间的申请、使用和释放
- 内存管理:开发者主动申请空间、使用空间、释放空间
- 管理流程:申请->使用->释放
一个手动书写的简单的申请、使用、释放:
// memory-manage
// 申请
let obj = {};
// 使用
obj.name = "yuuka";
// 释放
obj = null;
JavaScript中的垃圾回收
- JavaScript的内存管理是自动的
- 对象不再被引用到就是垃圾
- 对象不能从根上访问到时,就是垃圾
JavaScript的可达对象
- 可以访问到的对象就是可达对象(引用,作用域链)
- 可达的标准就是从根上出发是否能被找到
- JavaScript中的根就可以理解为全局变量对象
总结一下:JavaScript的垃圾回收,实际上就是,找到垃圾,然后让JavaScript执行引擎来进行空间的释放和回收
JavaScript代码中引用和可达
我们来点实际上的代码:
function objGroup(obj1, obj2) {
obj1.next = obj2;
obj2.prev = obj1;
return {
o1: obj1,
o2: obj2,
};
}
let obj = objGroup({ name: "obj1" }, { name: "obj2" });
console.log(obj);
这段代码。最后打印的结果是:
其中,Circular代表着循环引用
在这张图示里,从全局的一个根出发,我们可以找到一个可达的对象obj,他是通过一个函数调用之后,指向了一个内存空间,里面就是刚才我们看到的o1和o2,在o1和o2的里面,我们刚好通过相应的属性指向了一个obj1的空间和obj2的空间,对于他们俩来说,互相又通过next和prev属性做了一个互相引用,所以这样的过程里,我们代码里出现的对象,都可以通过根上进行查找,不论多么麻烦,总之都是可以找到的。
如果我们现在代码里做一个delete删除操作,把obj上的o1引用给delete,同时也把obj2里对obj1的引用也给delete掉。那么这一块儿的引用就是这样发生的:
对应在代码上就是delete了obj.o1和obj.o2.prev
说明了我们现在是没有办法再直接通过什么方式来找到obj1这样一个对象空间的。
也就是说:
obj1就会被认为是垃圾,最后JavaScript引擎就会找到他对其进行回收。
总结:在编写代码的时候,会存在一些对象引用的关系,我们可以从根的下面进行查找,按照链条,我们终归是能找到一些对象的,但是如果我们去找到这些对象的链条被破坏掉,或者是被回收掉了,那么这个时候我们是没有办法找到的,我们就会把他视作为垃圾,可以让垃圾回收机制将其回收掉