闭包到底有什么用?难道就是在外部访问内部函数吗?最关键最重要的用处在哪?
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
闭包有很多好处
首先 可以让一个子函数 使用父函数的作用域
其次 可以实现封装 比如 我返回几个东西
return {
a : function(){
},
b : function(){
}
}
还有很多 建议google baidu
楼下继续补充吧 哈哈
我是来补楼的,第一,闭包的理论知识各种社区已经介绍的够多了;闭包的实际应用多的数不清,我挑一篇近几个月读到的百度fex上的一篇文章推荐给题主-《Node.js Web应用代码热更新的另类思路》
里面有这样一处闭包的妙用,当然,如果要一下子理解这里为什么这么用肯定是不现实的。
题主不妨借这个机会去阅读一下express中app.use源码,然后再回过来细细品味这处妙用,相信你会对闭包有更深入的理解。
// app.js
var express = require('express');
var fs = require('fs');
var app = express();
var router = require('./router.js');
app.use(function (req, res, next) {
// 利用闭包的特性获取最新的router对象,避免app.use缓存router对象
router(req, res, next);
});
app.listen(3000);
// 监听文件修改重新加载代码
fs.watch(require.resolve('./router.js'), function () {
cleanCache(require.resolve('./router.js'));
try {
router = require('./router.js');
} catch (ex) {
console.error('module update failed');
}
});
function cleanCache(modulePath) {
require.cache[modulePath] = null;
}
一、匿名自执行函数
var data={
table"{},
tree:{}
};
(function(dm){
for(var i = 0; i < dm.table.rows; i++){
var row = dm.table.rows[i];
for(var j = 0; j < row.cells; i++){
drawCell(i, j);
}
}
})(data);
我们创建了一个匿名的函数,并立即执行,由于外部无法引用它内部的变量,因此在执行完后很快就会被释放,这种机制不会污染全局变量。
二、缓存
因为闭包不会释放外部的引用,所以可以实现缓存的功能。
var CachedSearchBox = (function(){
var cache = {},
count = [];
return {
attachSearchBox : function(dsid){
if(dsid in cache){//如果结果在缓存中
return cache[dsid];//直接返回缓存中的对象
}
var fsb = new uikit.webctrl.SearchBox(dsid);//新建
cache[dsid] = fsb;//更新缓存
if(count.length > 100){//保正缓存的大小<=100
delete cache[count.shift()];
}
return fsb;
},
clearSearchBox : function(dsid){
if(dsid in cache){
cache[dsid].clearSelection();
}
}
};
})();
CachedSearchBox.attachSearchBox("input1");
三、实现封装
var person = function(){
//变量作用域为函数内部,外部无法访问
var name = "default";
return {
getName : function(){
return name;
},
setName : function(newName){
name = newName;
}
}
}();
print(person.name);//直接访问,结果为undefined
print(person.getName());
person.setName("abruzzi");
print(person.getName());
得到结果如下:
undefined
default
abruzzi
四、实现对象
function Person(){
var name = "default";
return {
getName : function(){
return name;
},
setName : function(newName){
name = newName;
}
}
};
var john = Person();
print(john.getName());
john.setName("john");
print(john.getName());
var jack = Person();
print(jack.getName());
jack.setName("jack");
print(jack.getName());
运行结果如下:
default
john
default
jack
总结:可以访问父函数的作用域是它最重要的特性,它的应用都是基于这个特性而来,不存在最关键的应用场景,只能说上述几种比较常用而已。
你的问题没有提到javascript,不过我看所有人回答都是js....姑且就当你是问js里的闭包吧(虽然这对于闭包理解是本末倒置的)
js本身设计上有些问题(作用域的问题),以至于为了创造出局部作用域的量, 必须使用function, 而嵌套使用function又会让内层可以捕捉外层的自由变量, 其实大量使用闭包方式只是为了补救一开始的语言的设计问题(补救封装性)
如果js有其他语言中的namespace的等价物, 有其他语言的多种作用域关键字(for,try,if....)组合, 用闭包的情况会少很多.
除了这种情况外(补救js面向对象系统的缺陷), 还有少数情况(否则像C#这类有完整全面面向对象系统的语言干嘛也要支持闭包)一般发生在函数式编程的上下文中(js也是支持函数式编程的,并非一定要oo), 这跟其他函数式语言的闭包(除了scheme)的情况一样.
scheme语言里说的闭包一般是另外一种完全不同的东西,是数学上抽象代数里的 "闭包性质", 指的是一个函数作用于集合里的若干元素,得到返回值依然在集合里.我猜你想问的不会是这个,所以不展开了.
好吧我错了, 你tag里有 javascript了...虽然标题和内容没有