3 javascript闭包学习总结
2017-05-09 18:35
267 查看
闭包几个思想
javascript中有两种作用域,全局和局部,由于局部作用域的存在导致外部无法访问函数内部变量,从而出现了闭包思想。闭包的关键是作为沟通函数内外部的数据桥梁。//一个实现 function closure() { var innerVar = 0; function inner() { return ++innerVar;//可以直接修改innervar的值 } return inner; } var quote = closure(); echo(pclosure1, quote());//1 echo(pclosure1, quote());//2
js是函数作用域的,即一个function就是一个局部作用域,innerVar在函数作用域里面。但是希望能操作该内部变量。 那么其内部的函数就可以访问并修改这个局部变量。所以在第二次调用时,第一次调用的结果仍然保存着。
2:闭包中涉及的静态与动态作用于思想
var name = "xiaofu"; var person = function(lastname){ var name = 'yang'; function personName(){ return name + lastname; } return personName; } var pName = person(); pName("xiaoming");
js 中一个function就是一个作用域,所以personName在person这个函数的作用域里面。但是调用的是在这个作用域的外面,那么当personName执行的时候,它里面的name取的是person这个作用域还是最外层的作用域呢?
如果是静态作用域则调用的是person里面的 name, 如果是动态作用域则调用的是外层的name(“xiaofu”);而不是”yang”。
而闭包就是用来实现静态作用域的一种方式,即通过闭包将函数和它声明时的作用域保存下来,这样在调用的时候取到的就是声明时所在作用域 而不是调用时的作用域。
this
this则与变量有点不同,即this采用的是类似于动态作用域的情况。js里面一切都是对象,所以函数也都是某个对象的方法,如果没有显示指定则是全局对象window。
var person = { fullname: function{ console.log(this); }, printAge: function(){ console.log(this); } } person.fullname(); //this指向person var age = person.printAge; age(); //this指向window(浏览器中)
将person.printAge赋值给age之后,再执行age(),此时age没有显示指定调用对象则默认是window(浏览器环境)。所以this并不是声明所在的环境。
3箭头函数(es6)
es6中新增了箭头函数,箭头函数与通过function声明的函数不同,它的this是使用的声明时上下文中的this.并且不可通过apply, call等改变所以在使用箭头函数时一定要注意this指向问题。4 闭包的应用—立即执行函数
1:关键立即执行函数本身即是一个闭包2:闭包可以操作所在函数中的变量(利用这点锁住每次循环的变量值到内存中)
有个网友问了个问题,如下的html,为什么每次输出都是5,而不是点击每个p,就alert出对应的1,2,3,4,5。
<html > <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>闭包演示</title> <script type="text/javascript"> function init() { var pAry = document.getElementsByTagName("p"); for( var i=0; i<pAry.length; i++ ) { pAry[i].onclick = function() { alert(i); } } } </script> </head> <body onload="init();"> <p>产品一</p> <p>产品二</p> <p>产品三</p> <p>产品四</p> <p>产品五</p> </body> </html>
使用闭包可以解决异步加载问题:,
方法1、将变量 i 保存给在每个段落对象(p)上
“`
function init() {
var pAry = document.getElementsByTagName(“p”);
for( var i=0; i
**方法2、将变量 i 保存在匿名函数自身** ``` function init2() { var pAry = document.getElementsByTagName("p"); for( var i=0; i<pAry.length; i++ ) { (pAry[i].onclick = function() { alert(arguments.callee.i); }).i = i; } }
方法3、加一层闭包,i以函数参数形式传递给内层函数
function init3() { var pAry = document.getElementsByTagName("p"); for( var i=0; i<pAry.length; i++ ) { (function(arg){ pAry[i].onclick = function() { alert(arg); }; })(i);//调用时参数 } }
方法4、加一层闭包,i以局部变量形式传递给内存函数
function init4() { var pAry = document.getElementsByTagName("p"); for( var i=0; i<pAry.length; i++ ) { (function () { var temp = i;//调用时局部变量 pAry[i].onclick = function() { alert(temp); } })(); } }
方法5、加一层闭包,返回一个函数作为响应事件(注意与3的细微区别)
function init5() { var pAry = document.getElementsByTagName("p"); for( var i=0; i<pAry.length; i++ ) { pAry[i].onclick = function(arg) { return function() {//返回一个函数 alert(arg); } }(i); } }
方法6、用Function实现,实际上每产生一个函数实例就会产生一个闭包
function init6() { var pAry = document.getElementsByTagName("p"); for( var i=0; i<pAry.length; i++ ) { pAry[i].onclick = new Function("alert(" + i + ");");//new一次就产生一个函数实例 } }
方法7、用Function实现,注意与6的区别
function init7() { var pAry = document.getElementsByTagName("p"); for( var i=0; i<pAry.length; i++ ) { pAry[i].onclick = Function('alert('+i+')') } }
相关文章推荐
- JavaScript学习总结(十六)——Javascript闭包(Closure)
- JavaScript学习总结——Javascript闭包(Closure)
- javascript闭包学习总结
- JavaScript学习总结(十六)——Javascript闭包(Closure)
- JavaScript学习总结——我所理解的JavaScript闭包
- 蛙蛙推荐:蛙蛙学习asp.net总结(之一)
- 软件工程学习总结
- 前一段时间的学习总结
- 我的学习总结
- good,JSP学习经验总结
- 老猫的ASP.NET学习总结
- 学习ejb并配置一个简单的helloEjb是遇到问题后总结的经验。
- 一些C++连接,以及个人的C++学习总结。
- VC实例学习 (1):总结下今天学习的东西
- 2001 Microsoft Tech Ed (Beijing 2001/9/7 – 2001/9/9)学习总结
- 在自己学习stuts是遇到问题后总结的经验。
- 结合本人学习,总结一些C#和JAVA的不同这处
- 在自己学习stuts是遇到问题后总结的经验。
- 对前一段时间学习网络和多线程编程的总结
- VC学习资料收集(10):udp服务器设计过程总结