闭包(Closure)基础分析
闭包(Closure)
本文聚焦于回答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)基础分析的更多相关文章
- JavaScript闭包(Closure)
JavaScript闭包(Closure) 本文收集了多本书里对JavaScript闭包(Closure)的解释,或许会对理解闭包有一定帮助. <你不知道的JavsScript> Java ...
- 聊一下JS中的作用域scope和闭包closure
聊一下JS中的作用域scope和闭包closure scope和closure是javascript中两个非常关键的概念,前者JS用多了还比较好理解,closure就不一样了.我就被这个概念困扰了很久 ...
- python 函数对象(函数式编程 lambda、map、filter、reduce)、闭包(closure)
1.函数对象 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 秉承着一切皆对象的理念,我们再次回头来看函数(function).函 ...
- 深入理解JavaScript闭包(closure)
最近在网上查阅了不少javascript闭包(closure)相关的资料,写的大多是非常的学术和专业.对于初学者来说别说理解闭包了,就连文字叙述都很难看懂.撰写此文的目的就是用最通俗的文字揭开Java ...
- [转] Java内部类之闭包(closure)与回调(callback)
闭包(closure)是一个可调用的对象,它记录了一些信息,这些信息来自于创建它的作用域.通过这个定义,可以看出内部类是面向对象的闭包,因为它 不仅包含外围类对象(创建内部类的作用域)的信息,还自动拥 ...
- JavaScript 进阶(四)解密闭包closure
闭包(closure)是什么东西 我面试前端基本都会问一个问题"请描述一下闭包".相当多的应聘者的反应都是断断续续的词,“子函数”“父函数”“变量”,支支吾吾的说不清楚.我提示说如 ...
- [转载]学习Javascript闭包(Closure)
学习Javascript闭包(Closure) 源地址: http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures ...
- Swift语言精要-闭包(Closure)
闭包(Closure)这个概念如果没学过Swift的人应该也不会陌生. 学过Javascript的朋友应该知道,在Javascript中我们经常会讨论闭包,很多前端工程师的面试题也会问到什么是闭包. ...
- 【Python】闭包Closure
原来这就是闭包啊... 还是上次面试,被问只不知掉js里面的闭包 闭包,没听过啊...什么是闭包 回来查了下,原来这货叫闭包啊...... —————————————————————————————— ...
- 闭包(Closure)和匿名函数(Anonymous function)/lambda表达式的区别
闭包(Closure)和匿名函数(Anonymous function)/lambda表达式的区别 函数最常见的形式是具名函数(named function): function foo(){ con ...
随机推荐
- ArcGIS API for JavaScript根据两个点坐标在地图上画线
ArcGIS API for JavaScript根据两个点坐标在地图上画线比如说a(xxxx,xxxxx),b(xxxx,xxxxx).利用这两个点画一条线 var polyline = new e ...
- Mac 使用ab命令进行压测
Mac 使用ab命令进行压测 1.在Mac中配置Apache Mac中应该有自带了Apache,详细配置见http://www.cnblogs.com/snandy/archive/2012/11/1 ...
- java中byte, iso-8859-1, UTF-8,乱码的根源
Post@https://ryan-miao.github.io 背景 还是多语言, 在项目中遇到本地环境和服务端环境不一致乱码的情形.因此需要搞清楚乱码产生的过程,来分析原因. 获取多语言代码如下: ...
- 探索Windows命令行系列(2):命令行工具入门
1.理论基础 1.1.命令行的前世今生 1.2.命令执行规则 1.3.使用命令历史 2.使用入门 2.1.启动和关闭命令行 2.2.执行简单的命令 2.3.命令行执行程序使用技巧 3.总结 1.理论基 ...
- a链接返回上一页
<a href="javascript:void(0);" onclick="javascript:history.go(-1);" style='mar ...
- php7 安装yar 生成docker镜像
Docker包含三个概念:(1)远程仓库即远程镜像库所有镜像的聚集地(不可进入操作).(2)本地镜像即从远程仓库拉取过来的镜像(3)运行起来的本地镜像叫做容器(分层的可操作)Docker使用:1.首先 ...
- 【Android Developers Training】 37. 共享一个文件
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- I/O多路复用之epoll实战
概念 IO多路复用是指内核一旦发现进程指定的一个或者多个IO条件准备读取,它就通知该进程 通俗理解(摘自网上一大神) 这些名词比较绕口,理解涵义就好.一个epoll场景:一个酒吧服务员(一个线程),前 ...
- Openfire插件开发图解
概述 Openfire插件开发是Openfire的精髓之一,支持插件热插拔,还可以方便的在web端进行管理插件.插件分为两种,一种是以服务为主的控制台插件,一种是包括页面或对外开放Servlet接口. ...
- Java IO学习笔记(三)转换流、数据流、字节数组流
转换流 1.转换流:将字节流转换成字符流,转换之后就可以一个字符一个字符的往程序写内容了,并且可以调用字符节点流的write(String s)方法,还可以在外面套用BufferedReader()和 ...