开辟的堆内存或者造成的上下文(进栈执行=>栈内存)是越多越好,仍是越少越好?javascript
函数执行就会造成栈内存(从内存中分配的一块空间),若是内存都不销毁释放,很容易就会致使栈内存溢出(内存爆满,电脑就卡死了), => 因此JS中一个重要的性能优化点:减小内存的使用java
- =>释放堆内存
- =>释放栈内存(也就是让进栈执行的上下文,尽量出栈释放)
浏览器有自动回收垃圾的机制,按期间隔某段时间,把全部没有被占用的内存回收释放(这种垃圾回收机制,比其它语言要完善一些)web
若是堆内存用完后,咱们想去手动释放它,则取消全部的占用:赋值为NULL(NULL是空对象指针,也就是不指向任何的堆内存)浏览器
//=>建立一个引用类型值,就会产生一个堆内存
//若是当前建立的堆内存不被其它东西所占用了(浏览器会在空闲的时候,查找每个内存的引用情况,不被占用的都会给回收释放掉),则会释放
let obj = {
name : 'xiaozhima'
};
let oop = obj;
//此时obj和oop都占用着对象的堆内存,想要释放堆内存,须要手动解除变量和值的关联(null:空对象指针)
obj = null;
oop = null;
复制代码
栈内存:性能优化
- 打开浏览器造成的全局做用域是栈内存
- 手动执行函数造成的私有做用域是栈内存
- 基于ES6中的let/const造成的块做用域也是栈内存
- ......
栈内存销毁:bash
- 全局栈内存:关掉页面的时候才会销毁
- 私有栈内存:
- 1.通常状况下,函数只要执行完成,造成的私有栈内存就会被销毁释放掉(排除出现无限极递归、出现死循环的模式)
- 2.可是一旦栈内存中的某个东西(通常都是堆地址)被私有做用域之外的事物给占用了,则当前私有栈内存不能当即被释放销毁(特色:私有做用域中的私有变量等信息也保留下来了=>这种函数执行造成不能被释放的私有栈内存,也叫作闭包)
function fn(){
//...
}
fn(); //=>函数执行造成栈内存,执行完成栈内存销毁
function X(){
return function(){
//...
}
}
let f=X(); //=>f占用了X执行造成的栈内存中的一个东西(返回小函数对应的堆),则X执行造成的栈内存不能被释放了
复制代码
当前内存被其它东西引用了,则给堆计数1(累加计数),取消占用后,则减1,当减到零以后,浏览器就能够把它释放了闭包
var i = 5;
function fn(i) {
return function (n) {
console.log(n + (++i));
}
}
var f = fn(1);
f(2);
fn(3)(4);
fn(5)(6);
f(7);
console.log(i);
复制代码
let x = 5;
function fn(x) {
return function(y) {
console.log(y + (++x));
}
}
let f = fn(6);
f(7);
fn(8)(9);
f(10);
console.log(x);
复制代码
let a=0,
b=0;
function A(a){
A=function(b){
alert(a+b++);
};
alert(a++);
}
A(1);
A(2);
复制代码
var n=0;
function a(){
var n=10;
function b(){
n++;
console.log(n);
}
b();
return b;
}
var c=a();
c();
console.log(n);
复制代码
var test = (function(i){
return function(){
alert(i*=2);
}
})(2);
test(5);
复制代码