标签:
原博客标题:JS中的闭包(closure)原博客地址:http://www.cnblogs.com/jingwhale/p/4574792.html
笔记如下:
1. 函数内部声明变量的时候,一定要使用var命令。如果不用的话,实际上是声明了一个全局变量。
function outer(){ localVal = 30; return localVal; } outer();
alert(localVal);//30
2. Javascript语言特有的“链式作用域”结构(chain scope),子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。
比如在函数a内定义了函数b,那么a中所有局部变量都可以被b所访问到,然而b中所有局部变量a是不能访问的。
3. 简单的说,闭包(closure)就是能够读取其他函数内部(局部)变量的函数
由于在JavaScript中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
4. JavaScript中的函数定义
定义函数常用的两种方式: 函数声明,函数表达式
函数声明: function functionName(){ } 函数表达式: var functionName = function(){ } 可以使用函数表达式创建一个函数并马上执行它: (function() { var a, b // local variables // ... // and the code })()
JavaScript解析器处理两种方式的区别:
对于函数声明,js解析器会优先读取,确保在所有代码执行之前声明已经被解析;
对于函数表达式,如同定义其它基本类型的变量一样,只在执行到某一句时也会对其进行解析;
所以在实际中,处理两种函数定义方式的差异表现在,当使用函数声明的形式来定义函数时,可将调用语句写在函数声明之前;而使用函数表达式方式定义的函数时,这样做会报错。
5. 使用闭包的几种开发场景
使用自执行的匿名函数来模拟块级作用域, 从而限制向全局作用域中添加过多的变量和函数影响全局作用域: (function(){ // 这里为块级作用域 })(); 循环闭包: function showAllNum( aLi ){ for( var i =0,len = aLi.length ;i<len;i++ ){ aLi[i].onclick = function(){ alert( i );//all are aLi.length! } } } 点击后会一直弹出同一个值 aLi.length 而不是123。当点击之前,循环已经结束,i值为aLi.length。 改写如下 function showAllNum( aLi ){ for( var i =0,len = aLi.length ;i<len;i++ ){ aLi[i].onclick = (function(i){ return function(){ alert( i ); } })(i); } } 封装: var info = (function(){ var _userId = 23492; var _typeId = ‘item‘; function getUserId(){ alert(_userId); } function getTypeId(){ alert(_typeId); } })(); info.getUserId();//23492 info.getTypeId();//item info._userId//undefined info._typeId//undefined
6. JavaScript中的this
关于js中的this,记住谁调用,this就指向谁;要访问闭包的this,要定义个变量缓存下来。一般喜欢var _this = this。
7. IE9之前,JScript对象和COM对象使用不同的垃圾收集例程,那么闭包会引起一些问题。-- 内存泄漏
8. 闭包的原理 详见原博客
转载 - 读博客 - 笔记 - JS中的闭包(closure)
标签:
原文地址:http://www.cnblogs.com/simpeng/p/4575414.html