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闭包理解实例小结的更多相关文章

  1. js闭包理解

    js闭包的作用是使函数外可以访问函数内部的变量,是通过 在函数内部 定义 访问函数内变量 的函数实现的,内部的一个函数产生一个闭包 function a() { var i=0; return fun ...

  2. JS闭包理解_摘

    原文地址1:http://www.cnblogs.com/mzwr1982/archive/2012/05/20/2509295.html 闭包是一个比较抽象的概念,尤其是对js新手来说.书上的解释实 ...

  3. js闭包理解案例-解决for循环为元素注册事件的问题

      转发自http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html       一.变量的作用域 要理解闭包,首 ...

  4. js 闭包 理解

    1.什么是闭包 定义:是指有权访问另一个函数作用域中的变量的函数 创建闭包:在一个函数内部创建另一个函数 基本特点 在返回的匿名函数中 可以调用外部函数的变量 如下例中所示 内部函数(匿名函数) 可以 ...

  5. js 闭包 理解 copy

    闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 下面就是我的学习笔记,对于Javascript初学者应该是很有用的. 一.变量的作用域 要理解 ...

  6. js闭包理解与使用场景

    要理解闭包首先要知道什么是函数的作用域链 因为有函数的作用域链存在,所以函数无论在哪里调用,函数都可以使用函数外部作用域的变量. 当一个函数被调用时,会创建一个执行环境及相应的作用域链.然后使用arg ...

  7. js 闭包理解

    闭包主要应用于两种情况: 1 函数作为返回值. 2 函数作为参数传递. 第一种举例: function fn(){ var max = 10; return function bar(){ if(x ...

  8. 前端基本知识(三):JS的闭包理解

    JS闭包的理解 一.变量的作用域 二.如何从外部读取局部变量 三.什么是闭包 四.深入理解闭包 五.闭包的用途 六.使用闭包注意情况 七.JavaScript的垃圾回收机制 八.一些思考题 一.变量作 ...

  9. 前端基本知识(三):JS的闭包理解(第一个思考题有错误,已修改)

    JS闭包的理解 一.变量的作用域 二.如何从外部读取局部变量 三.什么是闭包 四.深入理解闭包 五.闭包的用途 六.使用闭包注意情况 七.JavaScript的垃圾回收机制 八.一些思考题 一.变量作 ...

随机推荐

  1. nyoj 82 迷宫寻宝(一)

    点击打开链接 迷宫寻宝(一) 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 一个叫ACM的寻宝者找到了一个藏宝图,它根据藏宝图找到了一个迷宫,这是一个很特别的迷宫,迷宫 ...

  2. QTEmbedded VCN实现

    1 在QT在第三方插件里加入VNC 进入\src\plugins\gfxdrivers\vnc,qmake -------make--------- make install 把目标文件夹gfxdri ...

  3. QWizard中运行时默认按钮显示英文问题

    QWizard中运行时默认按钮在编译前设计界面的时候是显示中文的,运行的时候就变成英文了.. 后来是发现国际化的时候有问题,解决办法如下: 在main.cpp里加: QTranslator* tran ...

  4. 02-自定义CALayer

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...

  5. Windows 2008 IIS7.0安装FTP教程 IIS7.5 配置多用户FTP

    一. 安装IIS.右键[我的电脑],选择[管理]打开.     选择[角色],选择[添加角色]打开.                   二. 配置DOS.输入: CACLS "%Syste ...

  6. Fiddler抓包工具的使用

    下载 自行去官网下载 http://www.telerik.com/fiddler 配置Fiddler 1.打开Fiddler, Tools-> Fiddler Options -> HT ...

  7. Xcode entitlement 问题定位和解决指南

    背景故事 前两天,本来一个运行正常.打包测试都没问题的XCode工程突然爆出各种奇怪的Entitlement错误: 什么签名的内容跟配置文件的不一致. 又或者 无法安装,因为签名或者配置文件的配置错误 ...

  8. Objective-C的内存管理

    一.Objective-C内存管理的对象 1. 值类型:比如int.float.struct等基本数据类型. 值类型会被放入栈中,在内存中占有一块连续的内存空间,遵循先进后出的原则,故不会产生碎片. ...

  9. Flex开发自定义控件

    前期准备: 点击File菜单 -> New -> MXML Component,然后弹出一个对话框. 在对话框中输入组件名,选择此组件继承的类型,如:Canvas,DataGrid,Com ...

  10. 解决服务器复制中SID冲突问题

    解决服务器复制中SID冲突问题 如果你有多部的主机需要安装,最快的方法是什么?想必就是用像GHOST之类的软件来进行硬盘的复制.当然,如果是安装在虚拟机之中,则需要复制虚拟的硬盘档案即可,以微软的VP ...