最近在学习前端知识,看到javascript闭包这里总是云里雾里。于是翻阅了好多资料记录下来本人对闭包的理解。

首先,什么是闭包?看了各位大牛的定义和描述各式各样,我个人认为最容易一种说法:

外部函数执行完成之后,内部函数依然可以访问外部函数的成员变量。这种现象叫做闭包

看看下面的代码:

function a () {
  var temp = "hello world";
  function b () {
    alert(temp);
  }
  return b;
 }
var test = a();
test();

这是一个经典闭包例子,b在执行的时候,a已经执行过了,但是b() 依然会返回"hello world",b函数是用了a函数的成员变量这就是闭包。

还有一个典型案例这里需要说明下:

html代码:

<div id="divTest">
  <span>0</span> <span>1</span> <span>2</span> <span>3</span>
</div>

js代码:

var spans = $("#divTest span");
  for (var i = 0; i < spans.length; i++) {
  spans[i].onclick = function () {
    alert(i);
  }
}

结果是每个span点击都弹出4,并不是我们想象的0,1,2,3

这因为在实际点击的时候还是能访问外部函数(外部函数已经执行结束,但是没有被销毁)的成员变量i,

由于每次外部函数在执行的时候都会重建作用域链中的变量,所以会发现循环了4次i之后,每个span的点击都是4。

一般解决这种闭包问题就是把公用的变量变成自己的,所以这样就这么解决。
var spans = $("#divTest span");
for (var i = 0; i < spans.length; i++) {
  spans[i].onclick = function () {
    var x = i;
    alert(x);
  }
}
这样大家都不公用父函数的,而是用自己的就正常了。
 
关于作用链只要记住以下几点就可以啦:
1.javascript中全局变量不能访问局部的变量,局部变量可以访问全局变量。
2.在局部中使用变量,如果当前函数中没有该变量,解析器会自动去父级作用域中寻找,如果父级没有会继续寻找更上一级的作用域,直到找到全局作用域如果还没有则返回undefined。
3.作用链就是逐级向上找的一个过程。
 

javascript闭包和作用域链的更多相关文章

  1. Javascript——闭包、作用域链

    1.闭包:是指有权访问另一个函数作用域中的变量的函数.创建闭包的常见方式:在一个函数内部创建另一个函数. function f(name){ return function(object){ var ...

  2. Javascript中闭包的作用域链

    作用域定义了在当前上下文中能够被访问到的成员,在Javascript中分为全局作用域和函数作用域,通过函数嵌套可以实现嵌套作用域. 闭包一般发生在嵌套作用域中.闭包是JavaScript最强大的特性之 ...

  3. javascript笔记:javascript的关键所在---作用域链

    javascript里的作用域是理解javascript语言的关键所在,正确使用作用域原理才能写出高效的javascript代码,很多javascript技巧也是围绕作用域进行的,今天我要总结一下关于 ...

  4. javascript的关键所在---作用域链

    javascript的关键所在---作用域链 javascript里的作用域是理解javascript语言的关键所在,正确使用作用域原理才能写出高效的javascript代码,很多javascript ...

  5. [ JS 进阶 ] 闭包,作用域链,垃圾回收,内存泄露

    原网址:https://segmentfault.com/a/1190000002778015 1. 什么是闭包? 来看一些关于闭包的定义: 闭包是指有权访问另一个函数作用域中变量的函数 --< ...

  6. JS闭包、作用域链、垃圾回收、内存泄露相关知识小结

    补充: 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 闭包的三个特性: 1.函数嵌套函数 2.函数内部可以引用外部的参数和变量 3.参数和变 ...

  7. JavaScript 中的闭包和作用域链(读书笔记)

    要想理解闭包,应当先理解JavaScript的作用域和作用域链. JavaScript有一个特性被称之为“声明提前(hoisting)”,即JavaScript函数里声明的所有变量(但不涉及赋值)都被 ...

  8. javascript深入浅出图解作用域链和闭包

    一.概要 对于闭包的定义(红宝书P178):闭包就是指有权访问另外一个函数的作用域中的变量的函数. 关键点: 1.闭包是一个函数 2.能够访问另外一个函数作用域中的变量 文章首发地址于sau交流学习社 ...

  9. [译]JavaScript:函数的作用域链

    原文:http://blogs.msdn.com/b/jscript/archive/2007/07/26/scope-chain-of-jscript-functions.aspx 在JavaScr ...

随机推荐

  1. ros下boost移植

    参考资料: http://blog.chinaunix.net/uid-12226757-id-3427282.html  注意:本链接中只看第一种的方法,验证程序参考以下: Boost安装成功的验证 ...

  2. Struts2 Interceptor学习

    Interceptor的设计思想,其实是Spring里面的AOP思想,尽管Struts2又有自己的Interceptor但是,在实际开发中,用的较少,SSH整合之后你可以采用AOP事务处理进行拦截,更 ...

  3. document.forms用法

    1.FF中不能接受document.forms("formname")的使用,ie中可以 最好改成document.forms["formname"]的下标用法 ...

  4. 物联网(莹石云)WIFI一键配置原理分析(zz)

    最近打算做一款自己的无线传输模块用来实现光伏电站的数据接入,希望可以尽量简化接入流程,其中wifi密码的配置就是一个比较麻烦的事情,想到最近使用萤石摄像头时,wifi密码配置似乎很简单,他们是怎么做到 ...

  5. 如何重复使用IEnumerable对象来枚举?

    我在2011年9月发表了一个问问,http://q.cnblogs.com/q/28679/. 没人理我. 自己看了一下,尝试自己解决: 原问题: MSDN: 在非泛型集合中,您可以在调用 Reset ...

  6. SQLite剖析之临时文件、内存数据库

    一.7种临时文件    SQLite中,一个数据库由单个磁盘文件构成,简化了SQLite的使用,因为移动或备份数据库只要拷贝单个文件即可.这也使得SQLite适合用作应用程序文件格式.但是,当在单个文 ...

  7. JS中的进制转换以及作用

    js的进制转换, 分为2进制,8进制,10进制,16进制之间的相互转换, 我们直接利用 对象.toString()即可实现: //10进制转为16进制 ().toString() // =>&q ...

  8. python基础回顾1

    定义 tuple(元组), list (表) #!/usr/bin/env python # encoding: utf-8 a = 10 #定义一直变量,无需声明 s1 = (2,1.3,'love ...

  9. 【UOJ#228】基础数据结构练习题 线段树

    #228. 基础数据结构练习题 题目链接:http://uoj.ac/problem/228 Solution 这题由于有区间+操作,所以和花神还是不一样的. 花神那道题,我们可以考虑每个数最多开根几 ...

  10. Spring 4支持的Java 8新特性一览

    有众多新特性和函数库的Java 8发布之后,Spring 4.x已经支持其中的大部分.有些Java 8的新特性对Spring无影响,可以直接使用,但另有些新特性需要Spring的支持.本文将带您浏览S ...