Javascript的一个特殊点就在于它的闭包和回调特性,这两个特性让初学Javascript的我是云里雾里,至今仍在苦苦摸索与理解。在一番苦思之后,整理了一下资料,将自己的理解思路记录下来,以免今后糊涂的时候再次作为索引,也希望能给和我同样的初学者带来理解上的一点帮助。

    要清楚地理解闭包,首先要有如下几个概念需要清楚:

作用域:
    作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期。

一切解释都没有例子来的清楚明白:

function say_hello(){
var words = "hello world!";
alert(words);
}
这里变量words的作用域就是括号“{”和“}”之间的范围。

作用链域:
    简单来说就是如果函数中需要用到的参数在本函数中有,则用本函数中的参数,如果没有则查询上一级函数中是否有,有则用之,没有则再次向上一级查询,直至找到或找不到为止(从最内层到最外层都没有)。这里不再多说,详细的说明见:Javascript中的作用链域
    继续看例子:
var str = "outer";
function outerFun(){
var str = "inner";
alert("------1------"+str);
function innerFun(){
str +="_new";
alert("------2------"+str);
}
innerFun();
alert("------3------"+str);
}
outerFun();
alert("------4------"+str);
//输出结果
------4------outer
------1------inner
------2------inner_new
------3------inner_new

这里可以看出函数outerFun内定义了str,但是最后的alert出的str却是“------4------outer",这说明外面是访问不到里面的变量,就是outerFun函数中的变量str的作用域在outerFun函数的花括号之间;但innerFun函数中

却可以访问外面outerFun中的str,这就是作用链域的作用了,即,本作用域内不存在的变量,就向上一级进行查找,如果该例子中outerFun中没有定义str,

那么就会是如下的情形:

var str = "outer";
function outerFun(){
alert("------1------"+str);
function innerFun(){
str +="_new";
alert("------2------"+str);
}
innerFun();
alert("------3------"+str);
}
outerFun();
alert("------4------"+str);
//输出结果
------4------outer
------1------outer
------2------outer_new
------3------outer_new
js的内存回收机制:
    一般一个函数在执行开始的时候,会给其中定义的变量划分内存空间保存,以备后面的语句所用,等到函数执行完毕返回了,这些变量就被认为是无用的了,对应的内存空间也就被回收了。下次再执行此函数的时候,所有的变量又回到最初的状态,重新赋值使用。
    但是,在Javascript中存在闭包的情形,所以回收机制会有点特殊。

闭包
    所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。
    这个定义十分的难以理解,远远的丢至一边,还是用简单的话解释一遍:多层嵌套的函数中,内层的函数能够访问包含它(或是它的上级)的函数的所有变量,同时能够通过回调使得其他作用域也可以使用这些变量。其实这一点就是作用链域的体现,这种特定的变量访问的方式我们就理解为Javascript的闭包特性。


匿名函数:
    简单来讲,一句话:没有函数名的函数。
var add = function(x,y){return x+y;}

    上句中右边就是一个匿名函数。同样,这是另一种定义方式。
(function(x,y){
alert(x+y);
})(3,5);

匿名函数与闭包的区别:由于见到匿名方式的闭包比较多,因此很多人将匿名函数和闭包理解为一个概念,其实要判别一个匿名函数是不是闭包,关键就是看是否通过回调将该函数所属函数中的变量传递给了其他的作用域。

顺便提一个《Javascript高级程序设计》中的闭包的一个例子,对于初学者来说可能相对较难理解(我是用了非常久才想明白的):
function createFunctions(){
var result = new Array();
for(var i=0;i<10;i++){
result[i] = function(){
return i;
}
}
return result;
}
    闭包内是对变量的引用,而非变量值的副本,也就是说result数组的每一项的值都是对变量i的引用,仅仅只是相当于一个指针,当i的值改变时,自然result的每一项的值也就随之改变,该例子中循环完之后i为10,所以每一项都是10。(其实还是比较好理解的哈,我当初不能理解【就是看了说明还是没能理解】的原因是没有把return
后的 i 当成是引用,而是将其当成值赋给了result数组...)
    所以,理解之后就很好改了:
function createFunctions(){
var result = new Array();
for(var i=0;i<10;i++){
result[i] = (function(num){
return num;
})(i);
}
return result;
};
 闭包内如何赋值给全局变量:
    这是今天最初的目标,顺便借这个机会,将这些都整理一遍,加深理解。最后解答一下这个简单问题,直接上例子:
<div id="info">
<ul></ul>
</div> function info(){
var strArr = [];
var data = [
{
"name":"Anny",
"age":"21",
"tel":"333333"
},
{
"name":"Bob",
"age":"33",
"tel":"232223"
},
{
"name":"Tom",
"age":"25",
"tel":"53344"
}
]
for(var i=0;i<data.length;i++){
strArr[i] = (function(obj){
return "姓名:"+obj.name+" 年龄:"+obj.age+" 电话:"+obj.tel;
})(data[i]);
}
return strArr;
}
var strArr = info();
$("#info ul").html("<li>"+strArr[0]+"</li><li>"+strArr[1]+"</li><li>"+strArr[2]+"</li>");

Javascript中闭包的个人理解的更多相关文章

  1. 在Javascript中闭包(Closure)

    在Javascript中闭包(Closure) 什么是闭包 “官方”的解释是:所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. ...

  2. javascript中闭包最简单的简绍

    javascript中闭包是什么 JavaScript 变量可以是局部变量或全局变量.私有变量可以用到闭包.闭包就是将函数内部和函数外部连接起来的一座桥梁. 函数的闭包使用场景:比如我们想要一个函数来 ...

  3. 在JavaScript中闭包的作用和简单的用法

    在JavaScript中闭包的作用和简单的用法 一.闭包的简介 作用域链:在js中只有函数有作用域的概念,由于函数内能访问函数外部的数据,而函数外部不能访问函数内部的数据,由上述形成一种作用域访问的链 ...

  4. 关于javascript中闭包的理解

    闭包就是能够读取其他函数内部变量的函数. 在javascript中,只有函数内部的子函数可以读取局部变量,因此,我理解闭包就是定义在一个函数内部的函数. 例子: var f1 = function() ...

  5. 对JavaScript中闭包的理解

    在前端开发中闭包是一个很重要的知识点,是面试中一定会被问到的内容.之前我对闭包的理解主要是"通过闭包可以在函数外部能访问到函数内部的变量",对闭包运用的也很少,甚至自己写过闭包自己 ...

  6. javascript中闭包与作用域的理解

    很多js的框架与插件编写都用到了闭包,所以,阅读和掌握闭包很有必要.最近学习vue框架时,经常会猜想很多功能的native js实现,很多都应用到了闭包,闭包除了目前已知的一些特性,如:可以保持局部变 ...

  7. 转:对JavaScript中闭包的理解

    关于 const     let      var  总结: 建议使用 let  ,而不使用var,如果要声明常量,则用const. ES6(ES2015)出现之前,JavaScript中声明变量只有 ...

  8. JavaScript中闭包之浅析解读

    JavaScript中的闭包真心是一个老生常谈的问题了,最近面试也是一直问到,我自己的表述能力又不能完全支撑起来,真是抓狂.在回来的路上,我突然想到了一个很简单的事情,其实我们在做项目时候,其实就经常 ...

  9. Javascript中闭包问题(转载)

    学习Javascript闭包(Closure)   作者: 阮一峰 日期: 2009年8月30日 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现 ...

随机推荐

  1. Python修改文件权限

    os.chmod()方法 此方法通过数值模式更新路径或文件权限.该模式可采取下列值或按位或运算组合之一: stat.S_ISUID: Set user ID on execution. stat.S_ ...

  2. POJ 3126 Prime Path (BFS+剪枝)

    题目链接:传送门 题意: 给定两个四位数a.b,每次能够改变a的随意一位.而且确保改变后的a是一个素数. 问最少经过多少次改变a能够变成b. 分析: BFS,每次枚举改变的数,有一个剪枝,就是假设这个 ...

  3. java.lang.UnsupportedOperationException解决方法!!!

    在项目中对List进行操作时报错java.lang.UnsupportedOperationException,后来发现操作的List是由数组转换而成的,通过看源码发现问题,并写测试程序如下. 代码块 ...

  4. redhat 网络配置

    1. 查看网络 ifconfig 网卡名字(eth0.wlan0) ifconfig -a //查看所有网卡配置 2. 网卡打开\关闭 ifconfig eth0 down ifconfig eth0 ...

  5. jquery的find()

    jQuery 遍历 - find() 方法 jQuery 遍历参考手册 实例 搜索所有段落中的后代 span 元素,并将其颜色设置为红色: $("p").find("sp ...

  6. iOS中三种方式实现登录界面播放视频或gif效果

    现在app都做的越来越炫酷,各种动画效果,各种特效很好的提高了用户的体验.很多app在登录界面都使用了动画效果,比如Uber,Keep,QQ等等.这些动画效果基本都是使用gif或者MP4来实现的. 效 ...

  7. 【深入JVM】JVM工具之JMAP

    一.工具介绍 假设把java\bin文件夹配置到环境变量.在cmd输入jmap会有例如以下提示: 翻译:打印出某个java进程(使用pid)内存内的,全部'对象'的情况(如:产生那些对象,及其数量). ...

  8. 【转】【FTP】之windows8.1上搭建FTP服务器方法

    参考地址:<windows8.1上搭建FTP服务器方法>

  9. 如何落地全球最大 Kubernetes 生产集群

        鲍永成   京东基础架构部技术总监,   DevOps 标准核心编写专家   前言   JDOS 就是京东数据中心操作系统,随着数据中心规模不断的扩大,我们需要对数据中心做综合的考虑.所以一开 ...

  10. JVM调优- 学习笔记(转)

    http://blog.csdn.net/fenglibing/article/details/6321453 GC学习笔记 这是我公司同事的GC学习笔记,写得蛮详细的,由浅入深,循序渐进,让人一看就 ...