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,执行闭包后,闭包内部变量会存在,而闭包内部函数的内部变量不会存在.
- js获取微信版本号
- mysql服务器端安装步骤(windows下jsp+mysql网站环境配置方法)
- jsfor循环是什么意思(JavaScript中三种for循环语句的使用总结for、for...in、for...of)
- 原生js实现轮播图代码(js实现轮播图制作方法)
- java上传图片压缩包(js实现多张图片打包成zip)
- js字符串常用函数
- nodejs如何识别接口(Node实现搜索框进行模糊查询)
- nodejs json文件读写(nodejs将JSON字符串转化为JSON对象报错的解决)
- js如何实现定时器功能(js实现0ms延时定时器的几种方式)
- vuejs filter过滤器的使用(Vue过滤器filter实现及应用场景详解)
- 通过js获取Url的参数值
- vue3 响应式的实现过程(Vue3.x使用mitt.js进行组件通信)
- node.js缓存区(如何利用node实现静态文件缓存详解)
- Extjs updateProgress进度条的应用
- python编写程序读写数据库(详解js文件通过python访问数据库方法)
- JS函数前面感叹号的作用
- 苹果正式发布自研芯片M1 5nm 32核心 彻底放弃Intel(苹果正式发布自研芯片M1)
- 苹果自研芯片跑分对比 A16芯片排名靠后,M1系列霸榜(苹果自研芯片跑分对比)
- X86处理器的梦魇 苹果M1自研芯片到底有多强(苹果M1自研芯片到底有多强)
- 泰剧《爱欲之神》Boom kitkong和Great合体杂志(泰剧爱欲之神Boomkitkong和Great合体杂志)
- 素人恋爱综艺火药味十足 男生为赢得芳心集体扯头花,真是出好戏(素人恋爱综艺火药味十足)
- 《囧妈》为何受抵制 春节七部影片撤档背后的责任与博弈(囧妈为何受抵制)
热门推荐
- python 正则表达式语法大全(python re库的正则表达式入门学习教程)
- css基线实例详解(移动端使用 rem 单位时 css sprites 定位问题的解决)
- zabbix如何监控访问状态码(基于zabbix实现监控Jenkins过程详解)
- 阿里云服务器公网ip搭建(阿里云服务器无公网如何上网?)
- javascript怎么生成html控件(JavaScript+html实现前端页面滑动验证2)
- canvas指定区域生成图片(canvas实现图片镜像翻转的2种方式)
- jquery next()
- mysql多表连接优化(浅谈Mysql多表连接查询的执行细节)
- Visual Studio 调试方法
- vue高阶组件怎么用(vue更多筛选项小组件使用详解)