已经记不清是哪个本书的哪个作者说过, 如果你不能把一个问题给6岁的孩子讲明白,那么你自己其实也还是没有明白
闭包这个概念其实已经被提及很多年了,java8是否支持闭包当初在csdn上也争论了许久(结果它弄了一个Lambda)
即便是现在出去找工作也经常会被问到, 什么是闭包 ( 相信我,我做面试官的时候从来没问过这个问题 )
今天觉得有必要重新整理一下关于闭包的知识
1 作用域
2 作用域
3 作用域
重要的事情说三遍
这里我们还是先以javascript为例
对变量作用域的控制 是javascript语言 实现闭包的必要手段
所谓的闭包, 在javascript中就是在函数B中(作用域B), 能够访问到函数A(作用域A)的变量
强调一下javascript只有全局变量(不带var),和局部变量(带var)
假设我们有函数A和函数B
function A(){
var test = 1;
…
}
function B(){
…
}
那么如何能使用函数B访问到函数A中的局部变量test呢 ( 当然了,如果你使用全局变量或者参数传递我们就不用在这啰嗦闭包了)
在javascript中, 只有一个函数内部的子函数,能访问这个函数的局部变量
接下来我们把这个函数修改一下,让函数B成为函数A的一部分
function A(){
var test = 1;
function B(){
test = test+1;
alert(test);
}
}
现在我们可以说, 这段代码是闭包了么, 是,但是也不完全是, 现在的问题是, 我们只是有一个函数和它的子函数,如何直接通过子函数(function B)来访问到主函数的局部变量(test)是眼前的问题,手段其实挺多的
1 你可以声明一个全局变量,然后指向函数B,这样你就可以在函数A的外部通过这个变量调用函数B
2 你还可以让函数A返回B,然后赋给一个全局变量
3 最后你还可以选择把函数B当参数传出来
第一种方式
<html>
<head>
<script type="text/javascript">
var global;
function A(){
var test = 1;
function B(){
test = test+1;
alert(test);
}
global = B;
}
function run(){
global();
}
A();
</script>
</head>
<body>
<input type="button" value="run" onclick="run()"/>
<div id="plane">
</div>
</body>
</html>
第二种方式(网上这种例子比较多哈)
<html>
<head>
<script type="text/javascript">
function A(){
var test = 1;
function B(){
test = test+1;
alert(test);
}
return B;
}
function run(){
global();
}
var global = A();
</script>
</head>
<body>
<input type="button" value="run" onclick="run()"/>
<div id="plane">
</div>
</body>
</html>
第三种方式(感觉是写起来最麻烦而且完全没必要,这里就是为了折腾一下)
<html>
<head>
<script type="text/javascript">
var global;
function A(){
if(test==undefined){
var test = 1;
}
function B(){
test = test+1;
alert(test);
}
transfer(B);
}
function transfer(fn){
global=fn;
}
function run(){
global();
}
A();
</script>
</head>
<body>
<input type="button" value="run" onclick="run()"/>
<div id="plane">
</div>
</body>
</html>