js闭包理解实例小结
Js闭包
闭包前要了解的知识
1. 函数作用域
(1).Js语言特殊之处在于函数内部可以直接读取全局变量
- <script type="text/javascript">
- var n=100;
- function parent(){
- alert(n);
- }
- parent();//
- </script>
如果在php里
- <?php
- $n=100;
- function parent(){
- echo $n;
- }
- parent();//会报错 n未定义
- ?>
(2).在函数外部无法读取函数内的局部变量
- <script type="text/javascript">
- function parent(){
- var m=50;
- }
- parent();
- alert(m);//报错 m未定义
- </script>
注意函数内部声明变量时一定要加var,否则就声明了一个全局变量
- function parent(){
- m=50;
- }
- parent();
- alert(m);//
- //当然在php里更是如此了,
- <?php
- function parent(){
- global $m;//全局 ,定义与赋值要分开
- $m=50;
- }
- parent();
- echo $m;//
- ?>
- //没global的话,一样会报没定义的错误
有时,需要得到函数内部的的局部变量,就需要变通的方法实现
利用js变量作用域的特点,如在函数内部定义子函数,对于子函数来说,父函数就是它的全局,子函数可以访问父函数里的变量(对于整个js代码来说又是局部变量)
- <script type="text/javascript">
- function parent(){
- var m=50;
- function son(){
- alert(m);
- }
- return son;
- }
- var s=parent();//将结果保存在全局里
- s();//
- </script>
Parent内部所有局部变量对其子函数来说都是可见的,但其子函数内的局部变量对其父函数是不可见的,这就是js特有的链式作用域结构,子对象会一级一级地向上查找所有父对象的变量,父对象的所有变量对子对象都是可见的,反之不成立!
上面的son函数就是闭包
有些同学可能这样
- function parent(){
- var m=50;
- function son(){
- alert(m);
- }
- }
- parent();
- son()//会报 函数son未定义
注意 在javascript里,在函数里声明的函数都是局部的,函数运行完后就释放了
注意这点与php的区别
- <?php
- function parent(){
- function son(){
- $m=50;
- echo $m;
- }
- }
- parent();
- son();//输出50 不会报错
- ?>
闭包
函数内部定义函数,连接函数内部和外部的桥梁
闭包的作用有2个:
一是前面提到的读取函数内部的变量,
二是让这些变量的值保存在内存中,实现数据共享
下面是几个闭包的例子
- <script type="text/javascript">
- var cnt=(function(){
- var i=0;
- return function(){
- alert(i);
- i++;
- }
- })();
- cnt();//
- cnt();//
- cnt();//
- cnt();//
- </script>
把匿名函数的执行结果(即对里面子函数的声明赋给全局变量cut),i就保存在内存里了
执行cut()时就直接从内存取值了,i只有cnt()函数才能调用,直接alert(i)是不行的
还可以向闭包内传参
- var cnt=(function(num){
- return function(){
- alert(num);
- num++;
- }
- })(5);
- cnt();//
- cnt();//
- cnt();//
- //当然还可以调用时传参
- var cnt=(function(){
- var i=0;
- return function(num){
- num+=i;
- alert(num);
- i++;
- }
- })();
- cnt(1);//
- cnt(2);//
- cnt(3);//
为了对闭包有更好的理解,我们看以下代码
比如我想返回一个数组,数组里面有5个函数,第一个函数弹出0,第二个弹出1...
代码如果这样写
- function box(){
- var arr=[];
- for(i=0;i<5;i++){
- arr[i]=function(){return i;}
- }
- return arr;
- }
- var a=box();
- alert(a);//包含五个函数体的数组
- alert(a[0]());
- alert(a[1]());
弹出的函数体
function(){return i;}
}
最后这个i是4,之后++成为5
For循环停止
发现均弹出5,明显不符合我们的要求
解决方案1
自我即时执行里面的函数
- function box(){
- var arr=[];
- for(i=0;i<5;i++){
- arr[i]=(function(num){return i;})(i);
- }
- return arr;
- }
- var a=box();
- for(var i=0;i<a.length;i++){
- alert(a[i]);
- }
但是我们发现 返回的数组里的元素是函数执行的结果,但我们想要的是函数
有得升级我们的代码
解决方案2 闭包实现
- function box(){
- var arr=[];
- for(var i=0;i<5;i++){
- arr[i]=(function(num){
- return function(){return num;}
- })(i);
- }
- return arr;
- }
- var arr=box();
- for(var i=0;i<5;i++){
- alert(arr[i]());//0,1,2,3,4
- }
关键代码
arr[i]=(function(num){
return function(){return num;}
})(i);
i=0 时
arr[0]=(function(num){return function(){return num;}})(0);
1时
arr[1]=(function(num){return function(){return num;}})(1);
这就是闭包的好处!
js闭包理解实例小结的更多相关文章
- js闭包理解
js闭包的作用是使函数外可以访问函数内部的变量,是通过 在函数内部 定义 访问函数内变量 的函数实现的,内部的一个函数产生一个闭包 function a() { var i=0; return fun ...
- JS闭包理解_摘
原文地址1:http://www.cnblogs.com/mzwr1982/archive/2012/05/20/2509295.html 闭包是一个比较抽象的概念,尤其是对js新手来说.书上的解释实 ...
- js闭包理解案例-解决for循环为元素注册事件的问题
转发自http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html 一.变量的作用域 要理解闭包,首 ...
- js 闭包 理解
1.什么是闭包 定义:是指有权访问另一个函数作用域中的变量的函数 创建闭包:在一个函数内部创建另一个函数 基本特点 在返回的匿名函数中 可以调用外部函数的变量 如下例中所示 内部函数(匿名函数) 可以 ...
- js 闭包 理解 copy
闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 下面就是我的学习笔记,对于Javascript初学者应该是很有用的. 一.变量的作用域 要理解 ...
- js闭包理解与使用场景
要理解闭包首先要知道什么是函数的作用域链 因为有函数的作用域链存在,所以函数无论在哪里调用,函数都可以使用函数外部作用域的变量. 当一个函数被调用时,会创建一个执行环境及相应的作用域链.然后使用arg ...
- js 闭包理解
闭包主要应用于两种情况: 1 函数作为返回值. 2 函数作为参数传递. 第一种举例: function fn(){ var max = 10; return function bar(){ if(x ...
- 前端基本知识(三):JS的闭包理解
JS闭包的理解 一.变量的作用域 二.如何从外部读取局部变量 三.什么是闭包 四.深入理解闭包 五.闭包的用途 六.使用闭包注意情况 七.JavaScript的垃圾回收机制 八.一些思考题 一.变量作 ...
- 前端基本知识(三):JS的闭包理解(第一个思考题有错误,已修改)
JS闭包的理解 一.变量的作用域 二.如何从外部读取局部变量 三.什么是闭包 四.深入理解闭包 五.闭包的用途 六.使用闭包注意情况 七.JavaScript的垃圾回收机制 八.一些思考题 一.变量作 ...
随机推荐
- Dubbo 服务暴露注册流程
Dubbo的应用会在启动时完成服务注册或订阅(不论是生产者,还是消费者)如下图所示. 图中小方块Protocol, Cluster, Proxy, Service, Container, Regist ...
- Oracle常用命令1
一. 安装是用户管理: sqlplus /nolog; connect /as sysdba; alter user sys identified by change_on_install; alte ...
- 判断Windows操作系统的版本
private void Form1_Load(object sender, EventArgs e) { if (!IsWin7()) { Application.Exit(); } } bool ...
- SVN提交数据失败问题(提示 svn:MKACTIVITY ... 403 Forbidden )
注册了淘宝svn,结果在代码提交是老是出问题,如下截图所示: 网上有常用的一种方法是: http://jingyan.baidu.com/article/67508eb4d3f2e29ccb1ce47 ...
- CodeForces 617C【序枚举】
题意: 有两个点喷水,有很多个点有花,给出坐标. 求使得每个花都可以被喷到,两个喷水的半径的平方的和最小是多少. 思路: 枚举其中一个喷水的最大半径. 坑: 这题我贪心的思路有很大问题.一开始也是想这 ...
- Java8新特性【转】
地址:http://ifeve.com/java-8-features-tutorial/ 1.简介 毫无疑问,Java 8是自Java 5(2004年)发布以来Java语言最大的一次版本升级,Ja ...
- 新建搜索bar
CGFloat enterW = self.view.frame.size.width - 80;// 245; CGFloat y = 0; containerView = [[UIVi ...
- android softinput 相关
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN | WindowManager.Layo ...
- 游戏服务器生成全局唯一ID的几种方法
在服务器系统开发时,为了适应数据大并发的请求,我们往往需要对数据进行异步存储,特别是在做分布式系统时,这个时候就不能等待插入数据库返回了取自动id了,而是需要在插入数据库之前生成一个全局的唯一id,使 ...
- TCP/IP详解学习笔记(10)-- DNS:域名系统
1.DNS DNS 是计算机域名系统(Domain Name System 或Domain Name Service) 的缩写,它是由解析器以及域名服务器组成的.域名服务器是指保存有该网络中 ...