闭包听了很多次了,可是到底有那些具体的用法还是不清楚,看了《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)的更多相关文章

  1. 深入理解JavaScript闭包(closure)

    最近在网上查阅了不少javascript闭包(closure)相关的资料,写的大多是非常的学术和专业.对于初学者来说别说理解闭包了,就连文字叙述都很难看懂.撰写此文的目的就是用最通俗的文字揭开Java ...

  2. JavaScript闭包(Closure)

    JavaScript闭包(Closure) 本文收集了多本书里对JavaScript闭包(Closure)的解释,或许会对理解闭包有一定帮助. <你不知道的JavsScript> Java ...

  3. [转载]学习Javascript闭包(Closure)

    学习Javascript闭包(Closure)     源地址: http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures ...

  4. 我从来不理解JavaScript闭包,直到有人这样向我解释它...

    摘要: 理解JS闭包. 原文:我从来不理解JavaScript闭包,直到有人这样向我解释它... 作者:前端小智 Fundebug经授权转载,版权归原作者所有. 正如标题所述,JavaScript闭包 ...

  5. javascript 闭包(closure)

    <script type="text/javascript">    //闭包(closure):内层函数可以引用存在于包围它的函数内的变量,即使外层函数的执行已经结束 ...

  6. 【转】深入理解JavaScript闭包闭包(closure) (closure)

    一.什么是闭包?"官方"的解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.相信很少有人能直接看懂这句话,因为他描述 ...

  7. 深入理解JavaScript闭包【译】

    在<高级程序设计>中,对于闭包一直没有很好的解释,在stackoverflow上翻出了一篇很老的<JavaScript closure for dummies>(2016)~ ...

  8. 深入理解javascript闭包(一)

    闭包(closure)是Javascript语言的一个难点.也是它的特色,非常多高级应用都要依靠闭包实现. 一.什么是闭包? 官方"的解释是:闭包是一个拥有很多变量和绑定了这些变量的环境的表 ...

  9. 深入理解javascript闭包(一)

    原文转自脚本之家(http://www.jb51.net/article/24101.htm) 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. ...

  10. 深入理解Javascript闭包概念

    一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部能够直接读取全局变量 ...

随机推荐

  1. C#基础知识-使用XML完成一个小程序(十一)

    上一篇中讲到XML基本的结构,还有增删改查的方法,这一篇中我们就来利用XML来完成一个简单的订单系统,主要是实现一个简单学生名单的增删改查,如果想要应用到实际的环境中建议考虑数据量的问题,如果数据量大 ...

  2. mac 好用软件地址存储

    Navicat Premium 12.0.24 for mac已破解中文 https://www.52pojie.cn/thread-727433-1-1.html sublime 破解方法https ...

  3. svn 创建本地仓库

    1. svnadmin create ~/repository 2. svnserve -d -r ~/repository 3. svn checkout file://~/repository $ ...

  4. java 反射实现2个int变量值的交换

    import java.io.*;import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; ...

  5. 把getJson() 设置为同步执行

    因为业务需求,需要在获取到json 数据后,对数据进行处理. 这时候,我们需要把getJson() 的方法设置为同步 $.ajaxSettings.async = false; getJson() 方 ...

  6. MySQL--主从数据库同步原理

    主从数据库的复制原理:摘自MySQL官网 1. 异步 * 主在执行sql之后,记录二进制bin-log文件.   * 同时从连接主服务器,并从主获取binlog,存于本地relay-log,并从上次记 ...

  7. 《火星救援》NASA惊现lisp

    duang-跳出个界面上面一个lisp程序.

  8. VC6.0开发OCX按钮控件

    原文:http://www.cnblogs.com/joinclear/archive/2013/05/21/3091934.html 0前言 1.OCX是典型的ActiveX控件,常见的OCX控件有 ...

  9. Vue2.0中的系统指令

    v-on注册事件 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> < ...

  10. 4.Linux文件系统层次体系标准

    这是不完整的linux文件系统层次体系标准,不是所有Linux发行版都根据这个标准,但大多数都是: 目录 评论 / 根目录,万物起源. /bin 包含系统启动和运行所必须的二进制程序. /boot 包 ...