JS中的堆栈内存及闭包详解

闭包

闭包作用(保护)

形成私有作用域,保护里面的私有变量不受外界的干扰

jQuery: 常用的 JS 类库,提供了很多项目中常用的方法(兼容所有浏览器)

Zepto:小型 JQ,专门为移动端开发准备的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/* JQ 代码片段 */
(function(window){
var jQuery = function(){、
// ...
};
// ...

window.jQuery = window.$ = jQuery;
})(window);

jQuery()
$()


/* Zepto 代码片段 */
var Zepto = (function(){
var Zepto = function(){
// ...
};
// ...
return Zepto;
})();
var $ = Zepto;
Zepto();
$();

真实项目中,我们利用这种保护机制,实现团队协作开发(避免了多人同一个命名,导致代码冲突的问题)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//	A
~function(){
// A 写的代码
function fn(){
// ...
}
window.fn = fn;
}();

// B
~function(){
// B 写的代码
function fn(){
// ...
}

// B 想要调取 A 写的 fn
window.fn();
}();

闭包作用(保存)

函数执行形成一个私有作用域,函数执行完成,形成的这个栈内存一般情况下都会自动释放

另外一种情况:函数执行完成,当前私有作用域(栈内存)中的某一部分内容被栈内存以外的其它东西(变量/元素的事件)占用了,当前的栈内存就不能释放掉,也就形成了不销毁的私有作用域(里面的私有变量也不会销毁)

1
2
3
4
5
6
7
8
9
10
11
12
function fn() {
var i = 1;
return function (n) {
console.log(n + i++);
}
}
var f = fn();

f(10); // 11
fn()(10); // 11
f(20); // 22
fn()(20); // 21

1550824611007

函数执行形成一个私有作用域,如果私有作用域中的部分内容被以外的变量占用了,当前作用域不销毁

【形式】

函数执行返回了一个 引用数据类型堆内存的地址 (并且堆内存隶属于这个作用域),在外面有一个变量接收了这个返回值,此时当前作用域就不能销毁(想要销毁,只需要让外面的变量赋值为 null,也就是不占用当前作用域中的内容了)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var num = 1,
obj = {
num: 2,
fn: (function(num) {
this.num *= 2;
num += 2;
return function () {
this.num *= 3;
num++;
console.log(num);
}
})(num)
};
var fn = obj.fn;
fn();
obj.fn();
console.log(num, obj.num);

1550825095361

闭包汇总

函数执行,形成一个私有作用域,保护里面的私有变量不受外界的干扰,这种保护机制叫做 闭包

但是现在一般认为:函数执行,形成一个不销毁的私有作用域,除了保护私有变量以外,还可以存储一些内容,这样的模式才是闭包

1
2
3
4
//	一个最简单的闭包
var utils = (function(){
return {}
})();
打赏功能
-------------本文结束感谢您的阅读-------------
0%