理解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语言的特殊之处,就在于函数内部能够直接读取全局变量 ...
随机推荐
- mybatis学习之动态sql
mybatis的动态sql语句很强大,在mapper映射文件中使用简单的标签即可实现该效果,下面一个个记录: 1.select查询 简单的select类似如下: <select id=" ...
- java泛型使用
泛型的解释 现在感觉泛型是一个值得学习的地方,就抽出时间来学习和总结一下泛型的使用. Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允 ...
- form表单在发送到服务器时候编码方式
enctype(编码方式):规定了form表单在发送到服务器时候编码方式.有如下的三个值可选: 1.application/x-www-form-urlencoded.默认的编码方式.但是在用文本的传 ...
- Mybatis插入、查询自定义的数据类型的方式
1.首先创建JavaBean对象 package com.zuo.Mybatis.bean; public class PhoneNumber { private String countryCode ...
- css-css的基本选择器(三种)
** 要对哪个标签里面的数据进行操作 (1)标签选择器 div { background-color:red; color:blue; } (2)class选择器 * 每个HTML标签中都有一个属性 ...
- canvas image array(canvas图片阵列)
code: <!DOCTYPE html> <html> <head> <title>hehe</title> </head& ...
- 软件项目技术点(1)——d3.interpolateZoom-在两个点之间平滑地缩放平移
AxeSlide软件项目梳理 canvas绘图系列知识点整理 软件参考d3的知识点 我们在软件中主要用到d3.js的核心函数d3.interpolateZoom - 在两个点之间平滑地缩放平移.请 ...
- jquery根据id取不到textarea对象,无法给textarea赋值
小编定义了一个textarea控件,却无法根据id取到textarea对象并赋值. 经过实验,得出了原因.代码如下: <!DOCTYPE html><html><head ...
- 大规模WEB服务技术
CPU负载的扩展很简单,增加相同结构的服务器,通过负载均衡来分散. I/O负载的扩展很困难.要考虑局部性.
- linux 安装源码后的操作 ldconfig
https://blog.csdn.net/cqkxboy168/article/details/8657487 知识点: .如果使用 ldd 命令时没有找到对应的共享库文件和其具体位置,可能是两种情 ...