闭包(Closure)

本文聚焦于回答2个问题:

  1. 在全局作用域中,如何读取函数内部的局部变量?
  2. 在全局作用域中,如何修改函数内部的局部变量?

变量作用域

JavaScript语言的作用域,一句话概括就是:内层函数可以访问外层函数的变量,而外层函

数不可以访问内层函数的变量。

在内层函数中定义的变量如果没使用var关键词,则该变量变为全局变量。通过这种方法定义

的全局变量,要在此函数执行后才有效。请看下面代码:

function outer() {
n = 820; function inner() {
he = 835;
} return inner;
} // console.log(n);
// n is not defined
// 上面的错误会打断程序执行,如要测试下面的代码,需注释掉上面的代码 outer();
console.log(n); // 820 // console.log(he);
// n is not defined (outer())();
console.log(he); // 835

如何从外部读取局部变量

通过闭包可以实现在全局作用域中访问函数内部变量。

function outer() {
var n = 820; function inner() {
return n;
} return inner;
} var k = (outer())();
console.log(k); // 820

outer()函数执行一次,将返回inner()函数的引用,再执行一次inner()

函数,就成功的把局部变量n返回出来。从而实现从外部读取内部变量。

如何从外部修改局部变量

通过闭包可以实现在全局作用域中修改函数内部变量。

var n = "hello";

function outer() {
var n = 820; function get() {
return n;
} function inc() {
n++;
} return {
n: n,
get: get,
inc: inc
};
} var result = outer(); console.log( result.n ); // 820
console.log( result.get() ); // 820 result.inc();
console.log( result.get() ); // 821
result.inc();
console.log( result.get() ); // 822 console.log( result.n ); // 820

outer()函数返回一个对象,这个对象有1个属性,2个方法。正常情况下一个

函数调用完毕,其内部的变量将会被垃圾回收机制(garbage collection)回收。

也就是说这些变量已经不存在内存中,也没有办法读取这些变量的值,更没法修改。

但是,我们把outer()函数的返回值赋给了一个全局变量,全局变量是始终存在

内存中的,而这个全局变量result又使用到了outer()函数的局部变量,所以

outer()函数的局部变量,不会被清除,将一直保存在内存中。

因此,只要我们执行一次result.inc(), outer()函数里面的n就会增加1。

而我们通过result.get()就可以访问到outer()函数里面的n。

要注意result.n的值始终是820,这里面的820只是n变量的一个副本,一旦

outer()函数执行完毕,result.n就和n没有关系了。

注意事项

由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包

,否则会造成网页的性能问题。

参考资料

http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html

闭包(Closure)基础分析的更多相关文章

  1. JavaScript闭包(Closure)

    JavaScript闭包(Closure) 本文收集了多本书里对JavaScript闭包(Closure)的解释,或许会对理解闭包有一定帮助. <你不知道的JavsScript> Java ...

  2. 聊一下JS中的作用域scope和闭包closure

    聊一下JS中的作用域scope和闭包closure scope和closure是javascript中两个非常关键的概念,前者JS用多了还比较好理解,closure就不一样了.我就被这个概念困扰了很久 ...

  3. python 函数对象(函数式编程 lambda、map、filter、reduce)、闭包(closure)

    1.函数对象 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 秉承着一切皆对象的理念,我们再次回头来看函数(function).函 ...

  4. 深入理解JavaScript闭包(closure)

    最近在网上查阅了不少javascript闭包(closure)相关的资料,写的大多是非常的学术和专业.对于初学者来说别说理解闭包了,就连文字叙述都很难看懂.撰写此文的目的就是用最通俗的文字揭开Java ...

  5. [转] Java内部类之闭包(closure)与回调(callback)

    闭包(closure)是一个可调用的对象,它记录了一些信息,这些信息来自于创建它的作用域.通过这个定义,可以看出内部类是面向对象的闭包,因为它 不仅包含外围类对象(创建内部类的作用域)的信息,还自动拥 ...

  6. JavaScript 进阶(四)解密闭包closure

    闭包(closure)是什么东西 我面试前端基本都会问一个问题"请描述一下闭包".相当多的应聘者的反应都是断断续续的词,“子函数”“父函数”“变量”,支支吾吾的说不清楚.我提示说如 ...

  7. [转载]学习Javascript闭包(Closure)

    学习Javascript闭包(Closure)     源地址: http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures ...

  8. Swift语言精要-闭包(Closure)

    闭包(Closure)这个概念如果没学过Swift的人应该也不会陌生. 学过Javascript的朋友应该知道,在Javascript中我们经常会讨论闭包,很多前端工程师的面试题也会问到什么是闭包. ...

  9. 【Python】闭包Closure

    原来这就是闭包啊... 还是上次面试,被问只不知掉js里面的闭包 闭包,没听过啊...什么是闭包 回来查了下,原来这货叫闭包啊...... —————————————————————————————— ...

  10. 闭包(Closure)和匿名函数(Anonymous function)/lambda表达式的区别

    闭包(Closure)和匿名函数(Anonymous function)/lambda表达式的区别 函数最常见的形式是具名函数(named function): function foo(){ con ...

随机推荐

  1. Swing系列之控件一

    Swing系列之控件 JTextArea JTextArea是一个实现多行文本的控件 构造函数 JTextArea() 构造新的TextArea. JTextArea(Document doc) 构造 ...

  2. Kubernetes服务之StatefulSets简介

    StatefulSets在v1.5时还是个beta特性,它取代了v1.4的PetSets特性.PetSets的用户可以参考v1.5的升级指导,将正在运行的PeetSets升级到StatefulSets ...

  3. 使用Spring mvc接收整个url地址及参数时注意事项

    使用Spring mvc接收整个url地址及参数时注意事项:url= http://baidu?oid=9525c1f2b2cd45019b30a37bead6ebbb&td=2015-08- ...

  4. ci框架中输出sql语句

  5. 使用Homebrew安装MySQL

    安装命令: brew install mysql 安装完成之后,启动mysql: mysql.server start 发现无此命令: command not found 首先,检查是否是安装了.重新 ...

  6. 如何判断浏览器为ie10以上

    如果针对ie10 以上单独写css样式的话,ie10以上已经不提供 <!--[if ...]><![endif]--> 这种方法去操作了,所以可以用css媒体查询的方法@med ...

  7. scrollMenu,一款可滚动的菜单插件 兼容pc和移动端

    这个菜单 有两种样式  , 也可以通过animate.css加不同的动画效果!滚动的方式也有两种   一种为通用的overflow,另外一种是better-scroll的滚动效果 在线链接地址  ht ...

  8. 转载文章之提供给开发者 10 款最好的 Python IDE

    Python 非常易学,强大的编程语言.Python 包括高效高级的数据结构,提供简单且高效的面向对象编程. Python 的学习过程少不了 IDE 或者代码编辑器,或者集成的开发编辑器(IDE).这 ...

  9. 安装GPU版本的tensorflow填过的那些坑!---CUDA说再见!

    那些坑,那些说不出的痛! --------回首安装的过程,真的是填了一个坑又出现了一坑的感觉.记录下了算是自己的笔记也能给需要的人提供一点帮助. 1 写在前面的话 其实在装GPU版本的tensorfl ...

  10. 我的学习之路_第三十章_servlet

    servlet:小服务程序 servlet是JavaWeb体系中的三大核心(servlet/Filter/Listener)之一,而且是最主要的那个. 作用:接受请求,处理请求,做出响应 继承体系:s ...