理解JavaScript闭包(closure)
闭包听了很多次了,可是到底有那些具体的用法还是不清楚,看了《JavaScript高级程序设计》,有点明白了。
1.闭包的定义:
闭包其实就是一个函数,而这个函数有点特别,它能够访问另一个函数作用域中的变量,所以一般我们看到的闭包存在形式都是在一个函数里面。
示例:
var iBaseNum = 10;//全局变量
function addNum(iNum1, iNum2) {//局部变量
function doAdd() {//闭包函数,有权访问局部变量中的iNum1, iNum2参数以及全局变量iBaseNum
return iNum1 + iNum2 + iBaseNum;
}
return doAdd();
}
2.闭包的用处
我们知道,当在函数内部定义了函数时,自然而然也就创建了闭包,闭包之所以强大,是因为它内部存在着一条作用域链。这条作用域包含着自己的作用域,包含函数的作用域和全局作用域。当代码在一个环境中执行时,会创建变量对象的一个作用域链。作用域链的用途是保证对执行环境有权访问的所有变量和函数的有序访问。
通常,当一个函数执行完了,它的作用域以及其所有变量都回在函数执行结束后被销毁。,但是当函数返回了一个闭包时,这个函数的作用域将会一直在内存中保存,直到闭包不存在为止。
了解了闭包的特性,我们就可以更好理解闭包有那些用途了,因为用途的实现是依赖于闭包的特性。
(1)模仿块级作用域
function outputNumbers(count){//没有闭包
for (var i=0; i < count; i++){
alert(i);
}
alert(i); //count
}
outputNumbers(5);
输出结果:0,1,2,3,4,5是alert(i)输出的。
for执行完了,i 还是存在于函数作用域中。
function outputNumbers(count){
(function () {//闭包函数,且立即执行
for (var i=0; i < count; i++){
alert(i);
}
})();
alert(i); //ReferenceError: i is not defined,出现错误了
outputNumbers(5);
输出结果:0,1,2,3,4
由于for在一个闭包函数里,当闭包函数执行完了,i也就销毁了,所以再在外部函数作用域在使用它就会出现未定义的情况了。
(2)创建私有变量
利用私有变量特性,我们就可以隐藏那些不应该被直接修改的数据了
私有变量定义:任何在函数中定义的变量,都可以认为是私有变量,因为不能在函数外部访问这些变量。私有变量包括函数的参数,局部变量和在函数内部定义的其他函数。
示例:
function add(num1,num2){
var sum=num1+num2;
return sum;
}//num1,num2,sum都是私有变量
私有作用域(块级作用域):只在内部可以使用,外部无法访问
示例:
//创建私有作用域
(function(){
//这里是私有作用域
})();//正确
//错误方法
function(){
//这里是私有作用域
}();//出错
JavaScript将function关键字当作一个函数申明的开始,而函数申明背后不能更圆括号,然而,函数表达式的后面可以跟圆括号,要将函数申明转换成函数表达式,只要将其放在一对圆括号中即可。
特权方法:我们把有权访问私有变量和私有函数的公有方法叫做特权方法。
示例:
function Person(name){//name是私有变量
this.getName = function(){//特权方法
return name;
};
this.setName = function (value) {
name = value;
};
}
var person = new Person("Nicholas");
alert(person.getName()); //"Nicholas"
person.setName("Greg");
alert(person.getName()); //"Greg"
上面示例中的getName()和setName()都可以在外部使用,都有权访问私有变量name。除了使用构造函数内部定义的这两个方法外,外部没有其他的任何办法可以访问name。
可以使用构造函数模式,原型模式来实现自定义类型的特权方法,也可以使用模块方式,增强的模块方式来实现单例的特权方法。
理解JavaScript闭包(closure)的更多相关文章
- 深入理解JavaScript闭包(closure)
最近在网上查阅了不少javascript闭包(closure)相关的资料,写的大多是非常的学术和专业.对于初学者来说别说理解闭包了,就连文字叙述都很难看懂.撰写此文的目的就是用最通俗的文字揭开Java ...
- JavaScript闭包(Closure)
JavaScript闭包(Closure) 本文收集了多本书里对JavaScript闭包(Closure)的解释,或许会对理解闭包有一定帮助. <你不知道的JavsScript> Java ...
- [转载]学习Javascript闭包(Closure)
学习Javascript闭包(Closure) 源地址: http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures ...
- 我从来不理解JavaScript闭包,直到有人这样向我解释它...
摘要: 理解JS闭包. 原文:我从来不理解JavaScript闭包,直到有人这样向我解释它... 作者:前端小智 Fundebug经授权转载,版权归原作者所有. 正如标题所述,JavaScript闭包 ...
- javascript 闭包(closure)
<script type="text/javascript"> //闭包(closure):内层函数可以引用存在于包围它的函数内的变量,即使外层函数的执行已经结束 ...
- 【转】深入理解JavaScript闭包闭包(closure) (closure)
一.什么是闭包?"官方"的解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.相信很少有人能直接看懂这句话,因为他描述 ...
- 深入理解JavaScript闭包【译】
在<高级程序设计>中,对于闭包一直没有很好的解释,在stackoverflow上翻出了一篇很老的<JavaScript closure for dummies>(2016)~ ...
- 深入理解javascript闭包(一)
闭包(closure)是Javascript语言的一个难点.也是它的特色,非常多高级应用都要依靠闭包实现. 一.什么是闭包? 官方"的解释是:闭包是一个拥有很多变量和绑定了这些变量的环境的表 ...
- 深入理解javascript闭包(一)
原文转自脚本之家(http://www.jb51.net/article/24101.htm) 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. ...
- 深入理解Javascript闭包概念
一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部能够直接读取全局变量 ...
随机推荐
- Silverlight & Blend动画设计系列十:Silverlight中的坐标系统(Coordinate System)与向量(Vector)运动
如果我们习惯于数学坐标系,那么对于Silverlight中的坐标系可能会有些不习惯.因为在Silverlight中的坐标系与Flash中的坐标系一样,一切都的颠倒的.在标准的数学坐标系中,X轴表示水平 ...
- 如何通过 PHP 获取 Azure Active Directory 令牌
在调用 Azure Rest API 时,如果是属于 Azure Resource Manager 的 API,则需要使用 Azure Active Directory (Azure AD)认证获取令 ...
- C#项目””是针对”.NETFramework,Version=v4.5.2”但此计算机没有,需要修改为v4.5.1.
每次下载别人的代码都会出现这样的问题,以为是没有安装.NETFramework,就下载安装了,但是每次安装都会出现已安装高版本的4.6(Win10自带),无需下次安装,但是每次VS中都会显示有问题,而 ...
- spring设置字符编码过滤器
一.在web.xml中的配置 <!-- characterEncodingFilter字符编码过滤器 --> <filter> <filter-name>chara ...
- Python基础学习总结(四)
6.高阶特性 6.1迭代 如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration).在Python中,迭代是通过for ... ...
- csharp:Learn how to post JSON string to generic Handler using jQuery in ASP.Net C#.
/// <summary> ///參考: http://james.newtonking.com/json/help/index.html# /// 塗聚文(Geovin Du) 2014 ...
- 跨域解决方案之HTML5 postMessage
问题场景: web是嵌入到手机客户端中的静态页面,为了统计用户行为需要引入ga,但是ga必须是在www下才行,哪怕是localhost,这就是矛盾.解决方案是在页面中使用iframe,iframe是在 ...
- CSS3,transform3D立体可拖拽正方体实现原理
---恢复内容开始--- 今天咱们来说一下,CSS中的3D效果 .如果你把transform真的掌握的和纯熟的话,就可以直接通过CSS做出很多很炫酷的效果,甚至.轮播图和选项卡都可以通过CSS来做,咱 ...
- JavaScript中的原型和原型链
1.原型是什么?原型链是什么? 原型是一个prototype对象,用于表示类型之间的关系: 原型链指的是在JavaScript中对象之间的继承是通过prototype对象指向父类对象,直到指向Obje ...
- java面试题之----IO与NIO的区别
JAVA NIO vs IO 当我们学习了Java NIO和IO后,我们很快就会思考一个问题: 什么时候应该使用IO,什么时候我应该使用NIO 在下文中我会尝试用例子阐述java NIO 和IO的区别 ...