js闭包与应用 关于Javascript闭包与应用的详解
Marshal_dj 人气:0想了解关于Javascript闭包与应用的详解的相关内容吗,Marshal_dj在本文为您仔细讲解js闭包与应用的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:js闭包与应用,js闭包,下面大家一起来学习吧。
前言
Javascript闭包在学习过程中一般较难理解,本文从什么是闭包,常见闭包示例,闭包作用,闭包应用及闭包问题等方面来介绍闭包,希望能给大家带来更深层次的认识,有不恰当之处请指出,谢谢。
一、什么是闭包?
闭包是指一个嵌套的内部(子)函数引用了父函数作用域中数据的函数,这就产生了闭包。
关键理解:
1. 产生闭包必须要有嵌套函数
2. 闭包是函数,并是嵌套的内部函数
3. 闭包内部函数必须要引用父函数作用域中数据
如果不满足以上条件,则不能产生闭包,接下来示例说明。
1.1闭包满足条件代码
<script> function person(){ var name='marshal'; function student(){ //声明子函数 console.log(name);//引用父函数作用域的变量name } } person();//函数执行,产生闭包 </script>
1.2闭包产生时机
<script> function person(){ var name='marshal';//js执行此行时,产生闭包 function student(){ //声明子函数 console.log(name);//引用父函数作用域的变量name } student();//内部函数在外部函数调用 } person();//函数执行,虽满足闭包条件,但未产生闭包 </script>
闭包产生时机:嵌套子函数代码块有引用父函数作用域的数据,并该嵌套子函数要执行前,创建上下文时产生闭包。或者简单说该该嵌套子函数在外部被执行时,此刻产生了闭包。
<script> function person(){ var name='marshal'; function student(){ console.log(name); //该方法代码内为闭包代码 } return student; } var p=person();//因创建子函数对像,此时产生第一次闭包,并将子函数student返回给p,由于p没有消失,子函数引用的变量name,一直在内存在存储,直到将p=null,进行回收 p();//执行子函数的闭包代码块,输出"marhsal" p();//第二次执行子函数的闭包代码块,输出"marhsal" person();//第二次创建子函数调对象,此时产生第二次闭包,但不执行子函数student代码块 </script>
二、常见闭包示例
2.1 子函数做为实参传递
<script> function setTimeoutTest(message,time){ setTimeout(function(){ alert(message);//嵌套子函数引用父函数变量message,产生闭包 },time); } setTimeoutTest('提示信息',1000); </script>
2.2 计数器使用(函数返回)
<script> function count(){ var i=1; function add(){ i++; console.log(i); } return add; } var c=count();//生产闭包 c();//2 c();//3 c();//4 </script>
三、闭包作用
3.1 闭包作用
1)子函数引用父函数的变量或函数,生命周期延长
2)其变量或函数一直存在,外部可以访问函数内部的值
<script> function count(){ var i=1; function add(){ i++; console.log(i); } return add; } var c=count(); c();//2 c();//3 i的生命周期延长 </script>
四、闭包应用
4.1 自定义封装js代码
外部js代码 out.js 实现自加与自减 (function count(){ var i=1; function add(){ i++; console.log(i); } function subtract(){ i-- console.log(i); } window.count={ add:add, subtract:subtract } })();
引用 out.js代码 <script src=out.js></script> <script> count.add(); //2 count.subtract();//1 count.subtract();//0 </script>
五、闭包问题
5.1 闭包与this
<script> var name="marshal"; //创建全局变量 var person={ name:"leo", getName:function(){ //返回匿名函数 return function(){ //返回this.name return this.name; //返回字符串 } } }; alert(person.getName()()); //输出marshal,内部函数不可能直接访问外部函数this </script>
解决方法
<script> var name="marshal"; var person={ name:"leo", getName:function(){ var that=this;//把this保存到闭包可以访问的另一个变量中 return function(){ return that.name; } } }; alert(person.getName()());//that 指向person,而不是window </script>
5.2 内存泄露
在使用闭包时,因变量一直存在,需要解除对象的引用,将对象设置为null, 从而确保其内存在适当时候可以被回收。
加载全部内容