闭包

概念

只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“。在本质上,闭包是将函数内部和函数外部连接起来的桥梁

例子

function outer(){
var localVal = 30;
return localVal;
} outer();//30 function outer(){
var localVal = 30;
return function() {
return localVal;
}
} var func = outer();
func();//30

作用:比如在一个函数中嵌套一个函数,通过闭包可以让嵌套函数访问到包裹它的函数的局部变量。

封装

(function(){
var _userId = 123;
var _typeId = 'item';
var MyExport = {}; function converter(userId){
return + userId;
} MyExport.getUserId = function(){
return converter(_userId);
} MyExport.getTypeId = function(){
return _typeId;
}
window.MyExport = MyExport;
})(); MyExport.getUserId();//123
MyExport.getTypeId();//item MyExport._uerId;//undefined
MyExport._typeId;//undefined
MyExport.converter;//undefined

闭包陷阱

var tasks = [];

for (var i=0; i<3; i++) {
tasks.push(function() {
console.log('>>> ' + i);
});
} console.log('end for.'); for (var j=0; j<tasks.length; j++) {
tasks[j]();
}

输出结果都为3。这个问题的原因在于,函数创建时并未执行,所以先打印end for.,然后才执行函数,由于函数引用了循环变量i,而i的作用域是整个函数,而不是循环,在函数执行时,i的值已经变成了3。

解决方法

再创建一个函数,将循环变量作为函数参数传入:

var tasks = [];

for (var i=0; i<3; i++) {
var fn = function(n) {
tasks.push(function() {
console.log('>>> ' + n);
});
};
fn(i);
} //简化语法,直接用匿名函数的立即执行模式(function() { ... })() var tasks = []; for (var i=0; i<3; i++) {
(function(n) {
tasks.push(function() {
console.log('>>> ' + n);
});
})(i);
}

总结

优点:灵活方便,封装

缺点:空间浪费,内存泄漏,性能消耗

JavaScript函数——闭包的更多相关文章

  1. javascript函数闭包(closure)

    一,首先感受下javascript函数的闭包 二,闭包 1,定义:闭包就是能够读取其他函数内部变量的函数,由于在javascript语言中,只有在函数内部的子函数才能够读取局部变量,因此可以把闭包简单 ...

  2. JavaScript 函数闭包的应用

    一.模仿块级作用域 JavaScript 没有块级作用域的概念,那么可以模拟像java中将很多变量私有化封装起来,保护数据,防止数据泄漏,封装细节,这样安全性和可控性更高 function box(c ...

  3. Javascript函数闭包详解(通俗易懂

    许多书上闭包过于复杂讲解难懂,自己理解了一下并总结啦~ 讲闭包之前,需要先明白以下几个概念. 总之,函数执行时所在的作用域,是定义时的作用域,而不是调用时所在的作用域. 1.执行上下文(executi ...

  4. JavaScript 函数闭包

    在函数中定义函数,这些定义的内部函数可以访问它们所在的外部函数中所有局部变量.参数以及声明的其它内部函数.当这样的内部函数在包含它们的外部函数之外被调用时就会形成闭包. 在没有class机制只有函数的 ...

  5. Javascript函数闭包及案例详解

    什么情况下会形成闭包,什么是闭包 闭包(Closure):函数和其周围的状态(词法环境)的引用捆绑在一起形成闭包 可以在另一个作用域中调用一个函数的内部函数并访问到该函数的作用域中的成员 下面来看一个 ...

  6. JavaScript碎片—函数闭包(模拟面向对象)

    经过这几天的博客浏览,让我见识大涨,其中有一篇让我感触犹深,JavaScript语言本身是没有面向对象的,但是那些大神们却深深的模拟出来了面向对象,让我震撼不已.本篇博客就是在此基础上加上自己的认知, ...

  7. JavaScript碎片———函数闭包(模拟面向对象)

    经过这几天的博客浏览,让我见识大涨,其中有一篇让我感触犹深,JavaScript语言本身是没有面向对象的,但是那些大神们却深深的模拟出来了面向对象,让我震撼不已.本篇博客就是在此基础上加上自己的认知, ...

  8. javaScript函数与闭包

    js中函数也是对象,具有一切对象的特征,可以作为表达式给变量赋值,可以作为函数的形参,或者函数的返回值,函数内可以嵌套函数等等,函数内以声明方式定义的函数是局部函数,用表达式声明的函数则由赋值变量的性 ...

  9. JavaScript 函数作用域和闭包

    函数作用域和闭包  词法作用域   它们在定义它们的作用域里运行,而不是在执行的作用域运行,但是只有在运行时,作用域链中的属性才被 定义(调用对象),此时,可访问任何当前的绑定.   调用对象     ...

随机推荐

  1. VUE 学习笔记 四 计算属性和监听器

    1.计算属性 对于任何复杂逻辑,你都应当使用计算属性 <div id="example"> <p>Original message: "{{ me ...

  2. SQL 增加列

    -- 判断是否存在该列 if exists(SELECT * FROM syscolumns WHERE id=object_id('@Table') and name='@COLUMN') ALTE ...

  3. WPF WindowStyle为None

    当WindwoStyle为None时 窗口会出现边框,不会完全覆盖窗口 修改办法: 使用AllowsTransparency="True"即可

  4. ClamAV学习【5】—— cli_scanpe函数浏览

    这近2000行的代码,要是没有Source Insight,都不知道怎么看下去.跟着跟着来到了PE文件查杀的地方,发现前面都中规中矩地进行PE属性检查,中间一段开始扫描每个区块,然后和特征库的size ...

  5. java—过虑器基础(47)

    在web项目中就只有三大组件: Filter过虑器 监听器. Servlet 在web中过虑器就是一个类javax.servlet.Filter. 过虑器是用于在执行时,过虑用户的请求(request ...

  6. 洛谷P5279 [ZJOI2019]麻将(乱搞+概率期望)

    题面 传送门 题解 看着题解里一堆巨巨熟练地用着专业用语本萌新表示啥都看不懂啊--顺便\(orz\)余奶奶 我们先考虑给你一堆牌,如何判断能否胡牌 我们按花色大小排序,设\(dp_{0/1,i,j,k ...

  7. acedSSGet 翻译

    ObjectARX 参考指南 > 全局函数 > AcEd 全局函数 > acedSSGet 函数 acedSSGet 折叠全部 C++ int acedSSGet( const AC ...

  8. javascriptdocument load 和document ready的区别

    页面加载完成有两种事件,一是ready , 表示文档结构已经加载完成(貋图片等非文字媒体文件),二是onload 指示页面包含图片等文件在内的所有元素都加载完成.   1.执行时间不同: 从字面的意思 ...

  9. Centos7下安装CUDA

    https://developer.nvidia.com/cuda-80-ga2-download-archive https://developer.nvidia.com/rdp/cudnn-dow ...

  10. 接口测试-postman,JMeter与LoadRunner比较

    postman是一个谷歌出的轻量级的专门测试接口的小工具~(PS:postman包括两种:Chrome浏览器插件和postman客户端,我使用的是postman客户端)虽然不如firefox的post ...