目录
一、闭包的定义
看了很多关于闭包的文章,对闭包的了解也有一定的头绪,但对与如何定义各有千秋,出发点不同所以理解也有各异,我的理解即
是反映javascript作用域关系的函数;
【示例一】
var name="xiaoli"
function _parent(){
function getName(){
console.log(name);
}
getName();
}
_parent(); //xiaoli
示例一:获取【name】值的执行顺序是,引擎先在执行作用域getName函数中寻找name的定义。
如果没有找到,则在当前作用域的上一级找;如果还是没有值则会再上一级找,直到找到name定义,否则会返回异常。
相信这个原理都可以理解,现在想下:子作用域可以顺利访问父作用域,那其他作用域能否访问当前作用域呢?就以上写法答案是”不行“,这就需要闭包登场。
二、闭包的组成元素
function _parent(){
var name="xiaobi";
return function (){
return name;
}
}
_parent()(); //xiaobi
示例二就是典型的一个闭包列子,函数_parent返回一个函数,此函数再返回对象,或者字面量,这就是闭包;
这样其他作用域可以直接访问_parent中的name,_parent()()只要放置不同位置即可,原因是代码执行完,name并未销毁,所以可以访问,否则就不属于闭包见示例三
function _parent(){
var name="xiaobi";
return name;
}_parent(); //xiaobi
示例三就属于正常写法,从上至下执行代码,结果打印,name变量就被销毁,所以不能称为闭包
三、闭包的应用场合
应用到的地方很多
1.数据缓存,因为缓存数据不需要销毁;以下是摘抄的示例四
var CachedBox = (function() {
var cache = {}, catchNameArr = [], catchMax = 10000;
return {
getCatch: function(name) {
if (name in cache) {
return cache[name];
}
var value = GetDataFromBackend();
cache[name] = value;
catchNameArr.push(name);
this.clearOldCatch();
return value;
},
clearOldCatch: function() {
if (catchNameArr.length > catchMax) {
delete cache[catchNameArr.shift()];
}
}
};
})();
2.递归函数;
3.输出循环体时内部数据,可以参考数据缓存的原理
总结
1.闭包是跨作用域的产物
2.闭包可以隔离作用域,保证变量不被污染
3.闭包的作用域是不能自动销毁的,需要手动销毁,所以会增加一点内存负担
4.此文章需要了解上下文作用域(JavaScript中的函数运行在它们被定义的作用域里,而不是它们被执行的作用域里.)
重新认识,每天进步一点点!