JavaScript函数——闭包
闭包
概念
只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“。在本质上,闭包是将函数内部和函数外部连接起来的桥梁
例子
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函数——闭包的更多相关文章
- javascript函数闭包(closure)
一,首先感受下javascript函数的闭包 二,闭包 1,定义:闭包就是能够读取其他函数内部变量的函数,由于在javascript语言中,只有在函数内部的子函数才能够读取局部变量,因此可以把闭包简单 ...
- JavaScript 函数闭包的应用
一.模仿块级作用域 JavaScript 没有块级作用域的概念,那么可以模拟像java中将很多变量私有化封装起来,保护数据,防止数据泄漏,封装细节,这样安全性和可控性更高 function box(c ...
- Javascript函数闭包详解(通俗易懂
许多书上闭包过于复杂讲解难懂,自己理解了一下并总结啦~ 讲闭包之前,需要先明白以下几个概念. 总之,函数执行时所在的作用域,是定义时的作用域,而不是调用时所在的作用域. 1.执行上下文(executi ...
- JavaScript 函数闭包
在函数中定义函数,这些定义的内部函数可以访问它们所在的外部函数中所有局部变量.参数以及声明的其它内部函数.当这样的内部函数在包含它们的外部函数之外被调用时就会形成闭包. 在没有class机制只有函数的 ...
- Javascript函数闭包及案例详解
什么情况下会形成闭包,什么是闭包 闭包(Closure):函数和其周围的状态(词法环境)的引用捆绑在一起形成闭包 可以在另一个作用域中调用一个函数的内部函数并访问到该函数的作用域中的成员 下面来看一个 ...
- JavaScript碎片—函数闭包(模拟面向对象)
经过这几天的博客浏览,让我见识大涨,其中有一篇让我感触犹深,JavaScript语言本身是没有面向对象的,但是那些大神们却深深的模拟出来了面向对象,让我震撼不已.本篇博客就是在此基础上加上自己的认知, ...
- JavaScript碎片———函数闭包(模拟面向对象)
经过这几天的博客浏览,让我见识大涨,其中有一篇让我感触犹深,JavaScript语言本身是没有面向对象的,但是那些大神们却深深的模拟出来了面向对象,让我震撼不已.本篇博客就是在此基础上加上自己的认知, ...
- javaScript函数与闭包
js中函数也是对象,具有一切对象的特征,可以作为表达式给变量赋值,可以作为函数的形参,或者函数的返回值,函数内可以嵌套函数等等,函数内以声明方式定义的函数是局部函数,用表达式声明的函数则由赋值变量的性 ...
- JavaScript 函数作用域和闭包
函数作用域和闭包 词法作用域 它们在定义它们的作用域里运行,而不是在执行的作用域运行,但是只有在运行时,作用域链中的属性才被 定义(调用对象),此时,可访问任何当前的绑定. 调用对象 ...
随机推荐
- ASP .NET运行机制(visio图)
- manual start user profile import
2 Sign in to vote Thanks Trevor, Finally created the task scheduled with this command: Sync Incremen ...
- 如何建立git 远程仓库
第1步:创建SSH Key.在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果已经有了,可直接跳到下一步.如果没有,打开Shell ...
- Nginx+keepalive 负载均衡
1 规划和准备 两台相同配置的web 用途 IP MASTER 192.168.1.100 BACKUP 192.1681.101 2 安装 两台接入服务器分别安装NginX和keepalived: ...
- 【timeisprecious】【JavaScript 】JavaScript RegExp 对象
JavaScript>RegExp正则表达式 1 .From Runnob JavaScript RegExp 对象(概览) JavaScript RegExp 对象(教程) RegExp 对象 ...
- 洛谷P5282 【模板】快速阶乘算法(多项式多点求值+MTT)
题面 传送门 前置芝士 \(MTT\),多项式多点求值 题解 这题法老当初好像讲过--而且他还说这种题目如果模数已经给定可以直接分段打表艹过去 以下是题解 我们设 \[F(x)=\prod_{i=0} ...
- HDU 3007 模拟退火算法
Buried memory Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ...
- sql注入原理详解(一)
我们围绕以下几个方面来看这个问题: 1.什么是sql注入? 2.为什么要sql注入? 3.怎样sql注入? 1.什么是sql注入? 所谓SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或 ...
- leetcode-350-Intersection of Two Arrays II(求两个数组的交集)
题目描述: Given two arrays, write a function to compute their intersection. Example:Given nums1 = [1, 2, ...
- string常用字符串操作函数
1.strdup和strndup 说明:strdup() 函数将参数 s 指向的字符串复制到一个字符串指针上去,这个字符串指针事先可以没被初始化.在复制时,strdup() 会给这个指针分配空间,使用 ...