闭包

概念

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

例子

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. centos6.6 下安装mysql5.7

    背景 没啥好说的,就是需要搭建自己的测试数据库跟研发的数据隔离开来,需要怼mysql 这个方法只适合mysql5.7 # mysql5.6的有差异 步骤 1. 确认线上mysql的版本 SELECT ...

  2. jenkins-cli命令使用总结

    jenkins-cli命令使用总结 1.在jenkins中查看Jenkins CLI的相关说明 jenkins-->系统管理-->Jenkins CLI:如下图 下载:jenkins-cl ...

  3. JS DOM对象控制HTML元素详解

    JS DOM对象控制HTML元素详解 方法: getElementsByName()  获取name getElementsByTagName()  获取元素 getAttribute()  获取元素 ...

  4. WPF文字间距

    代码: <ItemsControl ItemsSource="{Binding Info}" FontFamily="微软雅黑" FontSize=&qu ...

  5. util.Date转化成sql.date格式

    https://www.cnblogs.com/zhaotiancheng/p/6413067.html

  6. 修改 Cloud image 的密码的简单方法

    下载工具: yum -y install libguestfs-tools.noarch   打开DEBUG: export LIBGUESTFS_DEBUG=1 LIBGUESTFS_TRACE=1 ...

  7. java学习笔记—标准连接池的实现(27)

    javax.sql.DataSource. Java.sql.* DataSource 接口由驱动程序供应商实现.共有三种类型的实现: 基本实现 - 生成标准的 Connection 对象 – 一个D ...

  8. IDEA去除 xml 中Sql语句的背景

    去掉黄色背景 去掉绿色背景

  9. day03 --class --homework

    '''# >>>>>>2 :,有字符串s = "123a4b5c"#>>>>>^ 1: # 1)通过对s切片形成新 ...

  10. Linux之Ubuntu切换root su -

    当在Ubuntu系统从普通用户切换到root用户时,总是会报错,提示错误信息.这时因为我们还没有给系统中的root用户设置密码,我们给Ubuntu系统中的root用户设置一个密码就可以实现普通用户和管 ...