JavaScript 闭包初步
来源:互联网 发布:erp企业管理系统源码 编辑:程序博客网 时间:2024/06/14 13:10
JavaScript 闭包初步
内部类
我们先从一个基本的内部类开始
function outerFn() { document.write("Outer function<br/>"); function innerFn() { document.write("Inner function<br/>"); }}
假如我们想在outerFn()外调用innerFn()肿么办
function outerFn() { document.write("Outer function<br/>"); function innerFn() { document.write("Inner function<br/>"); }}innerFn();
上面的代码会出现JavaScript错误,那么该怎么调用呢?
伟大的逃逸
JavaScript允许开发人员像传递任何类型的数据一样传递函数,也就是说,JavaScript中的内部函数能够逃脱定义他们的外部函数。
逃逸方式一
var globalVar;function outerFn() { document.write("Outer function<br/>"); function innerFn() { document.write("Inner function<br/>"); } globalVar = innerFn;}outerFn();globalVar();
这种逃逸方式是:内部函数指定给一个全局变量
逃逸方式二
function outerFn() { document.write("Outer function<br/>"); function innerFn() { document.write("Inner function<br/>"); } return innerFn;}var fnRef = outerFn();fnRef();
这种逃逸方式是:通过在父函数的返回值来获得内部函数引用。
这种即使离开函数作用域的情况下仍然能够通过引用调用内部函数,意味着只要存在调用内部函数的可能,JavaScript就需要保留被引用的函数。而且JavaScript运行时需要跟踪引用这个内部函数的所有变量,直到最后一个变量废弃,JavaScript的垃圾收集器才能释放相应的内存空间.
闭包特性
闭包是指有权限访问另一个函数作用域的变量的函数
闭包的特性:
- 内部函数 也可以有自己的变量,这些变量都被限制在内部函数的作用域中。
function outerFn() { document.write("Outer function<br/>"); function innerFn() { var innerVar = 0; innerVar++; document.write("Inner function\t"); document.write("innerVar = "+innerVar+"<br/>"); } return innerFn;}var fnRef = outerFn();fnRef();fnRef();var fnRef2 = outerFn();fnRef2();fnRef2();
运行结果:
Outer function
Inner function innerVar = 1
Inner function innerVar = 1
Outer function
Inner function innerVar = 1
Inner function innerVar = 1
- 内部函数也可以像其他函数一样引用全局变量:
var globalVar = 0; function outerFn() { document.write("Outer function<br/>"); function innerFn() { globalVar++; document.write("Inner function\t"); document.write("globalVar = " + globalVar + "<br/>"); } return innerFn;}var fnRef = outerFn();fnRef();fnRef();var fnRef2 = outerFn();fnRef2();fnRef2();
运行结果:
Outer function
Inner function globalVar = 1
Inner function globalVar = 2
Outer function
Inner function globalVar = 3
Inner function globalVar = 4
父函数的局部变量被内部类引用(有兴趣可以了解一下作用域链和活动对象的知识)
function outerFn() {var outerVar = 0;document.write("Outer function<br/>");function innerFn() { outerVar++; document.write("Inner function\t"); document.write("outerVar = " + outerVar + "<br/>");}return innerFn;}var fnRef = outerFn();fnRef();fnRef();var fnRef2 = outerFn();fnRef2();fnRef2();
这一次结果非常有意思,也许或出乎我们的意料
Outer function
Inner function outerVar = 1
Inner function outerVar = 2
Outer function
Inner function outerVar = 1
Inner function outerVar = 2
我们看到的是前面两种情况合成的效果,通过每个引用调用innerFn都会独立的递增outerVar。也就是说第二次调用outerFn没有继续沿用outerVar的值,而是在第二次函数调用的作用域创建并绑定了一个一个新的outerVar实例,两个计数器完全无关。
闭包的交互
function outerFn() { var outerVar = 0; document.write("Outer function<br/>"); function innerFn1() { outerVar++; document.write("Inner function 1\t"); document.write("outerVar = " + outerVar + "<br/>"); } function innerFn2() { outerVar += 2; document.write("Inner function 2\t"); document.write("outerVar = " + outerVar + "<br/>"); } return { "fn1": innerFn1, "fn2": innerFn2 };}var fnRef = outerFn();fnRef.fn1();fnRef.fn2();fnRef.fn1();var fnRef2 = outerFn();fnRef2.fn1();fnRef2.fn2();fnRef2.fn1();
运行结果:
Outer function
Inner function 1 outerVar = 1
Inner function 2 outerVar = 3
Inner function 1 outerVar = 4
Outer function
Inner function 1 outerVar = 1
Inner function 2 outerVar = 3
Inner function 1 outerVar = 4
innerFn1和innerFn2引用了同一个局部变量,因此他们共享一个封闭环境。当innerFn1为outerVar递增一时,就为innerFn2设置了outerVar的新的起点值,反之亦然。我们也看到对outerFn的后续调用还会创建这些闭包的新实例,同时也会创建新的封闭环境,本质上是创建了一个新对象,自由变量就是这个对象的实例变量,而闭包就是这个对象的实例方法,而且这些变量也是私有的,因为不能在封装它们的作用域外部直接引用这些变量,从而确保了了面向对象数据的专有性。
看完上面的基本知识,你或许对闭包有了一个比较浅显的认识,学过C/C++的同学应该理解起来比较容易,因为闭包特别像是指针函数,但是有不是完全是,因为还有作用域的概念。如果想更深入的认识闭包可以进一步学习JavaScript作用域链和活动对象。
本文转自:http://www.cnblogs.com/dolphinX/archive/2012/09/29/2708763.html 部分内容做了修改,特此说明。
- JavaScript 闭包初步
- 初步了解javascript闭包
- 初步了解Javascript 闭包
- javascript之初步理解闭包
- 初步理解闭包
- 初步了解闭包
- 闭包初步感受
- js 初步了解闭包
- 【JavaScript】Javascript闭包
- Javascript初步
- javascript初步.
- JavaScript初步
- javascript的闭包javascript
- Javascript闭包演示javascript
- [ javascript ] javascript闭包测试!
- 【javascript】javascript中的闭包
- 【javascript】学习Javascript闭包
- 理解 JavaScript 闭包
- 22个很棒的jQuery文件上传插件
- 分享一个链接
- 获取当前显示的ViewController
- 用UpdateLayeredWindow实现任意异形窗口
- ios 上传多张图片总结——IOS网络访问之使用AFNetworking
- JavaScript 闭包初步
- CSS居中对齐
- 微软100题(56)最长公共子序列
- 欢迎使用CSDN-markdown编辑器
- 分布式MySQL数据库TDSQL架构分析
- Android 图片的三级缓存 及 图片压缩
- java处理Excel文件---excel文件的创建,删除,写入,读取
- 雕塑对于城市的重要性
- java中split方法为何不能用小数点(.)做参数?