JS闭包的用法
JS闭包的用法
JS闭包的用法一、闭包的概念:
闭包是可以包含自由(未绑定到特定对象)变量的代码块;这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变量)。“闭包” 一词来源于以下两者的结合:要执行的代码块(由于自由变量被包含在代码块中,这些自由变量以及它们引用的对象没有被释放)和为自由变量提供绑定的计算环境(作用域)。在编程领域我们可以通俗的说:子函数可以使用父函数中的局部变量,这种行为就叫做闭包!
二、闭包的作用:
在说闭包的作用之前,让我们来先看看下面一段代码:
<script type="text/javascript"> function test1(){ var i=0; function test2(){ alert(++i); } return test2; } var temp = test1(); temp(); </script>运行这段代码后,我们发现,弹出窗的结果是:1。
三、闭包的价值
四、闭包的两个特点:
1、作为一个函数变量的一个引用 - 当函数返回时,其处于激活状态。
2、一个闭包就是当一个函数返回时,一个没有释放资源的栈区。
其实上面两点可以合成一点,就是闭包函数返回时,该函数内部变量处于激活状态,函数所在栈区依然保留.
我们所熟知的主流语言,像C,java等,在函数内部只要执行了return,函数就会返回结果,然后内存中删除该函数所在的区域.生命周期也就停止了.一般的js函数也是这样.但是有闭包特性的js函数有点特殊.
五、闭包的样例
前面的我大致了解了Javascript闭包是什么,闭包在Javascript是怎么实现的。下面我们通过针对一些例子来帮助大家更加深入的理解闭包
例子1:闭包中局部变量是引用而非拷贝
//因此执行结果应该弹出的667而非666。
function say667() {
// Local variable that ends up within closure
var num = 666;
var sayAlert = function() { alert(num); }
num++;
return sayAlert;
}
var sayAlert = say667();
sayAlert()
例子2:多个函数绑定同一个闭包,因为他们定义在同一个函数内。
function setupSomeGlobals() {
// Local variable that ends up within closure
var num = 666;
// Store some references to functions as global variables
gAlertNumber = function() { alert(num); }
gIncreaseNumber = function() { num++; }
gSetNumber = function(x) { num = x; }
}
setupSomeGlobals(); // 为三个全局变量赋值
gAlertNumber(); //666
gIncreaseNumber();
gAlertNumber(); // 667
gSetNumber(12);//
gAlertNumber();//12
例子3:当在一个循环中赋值函数时,这些函数将绑定同样的闭包
//testList的执行结果是弹出item3 undefined窗口三次,因为这三个函数绑定了同一个闭包,而且item的值为最后计算的结果,但是当i跳出循环时i值为4,所以list[4]的结果为undefined.
function buildList(list) {
var result = [];
for(var i = 0; i < list.length; i++) {
var item = 'item'+ list[i];
result.push( function() {alert(item + ' '+ list[i])} );
}
return result;
}
function testList() {
var fnlist = buildList([1,2,3]);
// using j only to help prevent confusion - could use i
for(var j = 0; j < fnlist.length; j++) {
fnlist[j]();
}
}
例子4:外部函数所有局部变量都在闭包内,即使这个变量声明在内部函数定义之后。
//执行结果是弹出”Hello Alice”的窗口。即使局部变量声明在函数sayAlert之后,局部变量仍然可以被访问到。
function sayAlice() {
var sayAlert = function() { alert(alice); }
// Local variable that ends up within closure
var alice = 'Hello Alice';
return sayAlert;
}
var helloAlice=sayAlice();
helloAlice();
例子5:每次函数调用的时候创建一个新的闭包
function newClosure(someNum, someRef) {
// Local variables that end up within closure
var num = someNum;
var anArray = [1,2,3];
var ref = someRef;
return function(x) {
num += x;
anArray.push(num);
alert('num: '+ num +
'\\nanArray '+ anArray.toString() +
'\\nref.someVar '+ ref.someVar);
}
}
closure1=new Closure(40,{someVar:'closure 1'});
closure2=new Closure(1000,{someVar:'closure 2'});
closure1(5); // num:45 anArray[1,2,3,45] ref:'someVar closure1'
closure2(-10);// num:990 anArray[1,2,3,990] ref:'someVar closure2'
六、使用闭包的注意点
1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
七、好了,总结下
1,闭包外层是个函数.
2,闭包内部都有函数.
3,闭包会return内部函数.
4,闭包返回的函数内部不能有return.(因为这样就真的结束了)
5,执行闭包后,闭包内部变量会存在,而闭包内部函数的内部变量不会存在.
- python json转换字符串(python3 json数据格式的转换dumps/loads的使用、dict to str/str to dict、json字符串/字典)
- extjs checkboxGroup 复选框的用法
- tomcat服务如何在eclipse中配置(HBuilderX配置tomcat外部服务器查看编辑jsp界面的方法详解)
- js实现string.format 字符串占位符
- JavaScriptSerializer对Json对象的序列化和反序列化
- packagejson怎么使用(最全的package.json解析)
- js中this的用法
- mysql服务器端安装步骤(windows下jsp+mysql网站环境配置方法)
- nodejs的广播机制(node.js如何自定义实现一个EventEmitter)
- vue多个对象实现双向数据绑定(利用js实现Vue2.0中数据的双向绑定功能)
- vuejs过滤器使用教程(vue3删除过滤器的原因)
- js对日期加减指定天、时、分、秒
- extjs XTemplate的实例
- 使用vue-cli构建electron项目(MAC+PyCharm+Flask+Vue.js搭建系统)
- JS闭包的用法
- js浮点数运算精度问题(JS超出精度数字问题的解决方法)
- 世界上只有妈妈好(世界上只有妈妈好的歌词)
- 为什么现在社会越来越卷了(现在社会为什么发展那么快呢)
- 直播带货能赚到很多钱吗(直播带货能赚到很多钱吗现在)
- 做网红真的很能赚钱吗(做网红真的很能赚钱吗)
- 10句英语常用(英语常用900句)
- 爱情能当饭吃吗(爱情能当饭吃吗说说)
热门推荐
- dedecms文章内容页调用自定义字段(DEDECMS教程:上/下一篇文章标题长度的截取方法)
- sql server使用手册(SQL Server连接查询的实用教程)
- dedecms自定义联动类别方法(DEDECMS点击主栏目默认显示第一个子栏目列表的方法)
- pythonlist类型教程(Python List cmp知识点总结)
- dedecms5.7使用教程(dedecms v5.7提示php.ini register_globals must is Off错误的解决方法)
- centos上docker的部署(CentOS8下的Docker使用详解)
- sqlserver连接字符串函数(SQL SERVER 2012新增函数之字符串函数FORMAT详解)
- 卸载了云服务器后怎么办(云服务器怎么还原被删除的数据?)
- 简单的肖特基二极管电路(两个元祖T1='a', 'b',T2='c', 'd'使用匿名函数将其)
- mysql获取当前日期时间(MySQL DATEDIFF函数获取两个日期的时间间隔的方法)