常见面试题JavaScript闭包(ES5语法)
JavaScript闭包(Closure)是常见的JS面试题,是否理解闭包是一个简单的区分JS初级和高级程序员的判例。
几乎每个JS程序员都在使用闭包,有意或无意间。比如编写一个jQuery鼠标点击处理函数:
$(function() { var option; $(".scssbox").click(function() { // 闭包,该闭包同时也是一个匿名函数 option = scss; // 闭包可以访问和改变其外部函数(包含函数)中的变量 }); }
什么是闭包
“闭包”实际上就是一个函数,该函数被定义在一个包容(外部)函数的内部,并能够访问外部函数的变量,即使外部函数已返回。
这种外部变量访问能力不是通过数值拷贝传递,而是通过引用(Reference)传递的,因此闭包可以读取并改变外部变量的取值。
function Name (firstName, lastName) { var nameIntro = "Your name is "; // 该内部函数能访问外部函数中定义的变量,以及参数 function makeFullName () { return nameIntro + firstName + " " + lastName; } return makeFullName (); } console.log( Name("Michael", "Jordan") ); // Your name is Michael Jordan
注意:上述代码中的闭包不能被公开函数(public function)所调用,另外闭包不能访问外部函数的arguments变量。所谓公开函数指的是通过原型(prototype)扩展来定义的对象函数。
为什么需要闭包
闭包的好处是可以方便的完成外部函数对象的某些特定功能。
我们可以类比C++等其他面向对象的语言,访问控制是面向对象语言的一个基本特征,
而通过闭包,我们可以在JS语言中实现对象私有成员函数(private member function)和授权函数的功能。
闭包的陷阱
由于闭包能够修改外部函数变量,如果不小心,可能会产生一些比较隐蔽的问题:
function Member(users) { var i; var uniqueID = 100; for (i = 0; i < users.length; i++) { users[i]["id"] = function() { return uniqueID + i; } } return users; } var users = [{ name: "Ryan", id: 0 }, { name: "Mike", id: 0 }, { name: "Mark", id: 0 }]; var members = Member(users); var rid = members[0]; console.log(rid.id()); // 103
上面的代码本来是想给3个用户分别分配唯一成员编号100、101、102,但实际上都是103。
原因就是在调用Member函数并返回后,i已经被修改为3,那么当再次调用闭包函数获取唯一编号时就已经是103。
你可以自己在线试试看。
- 相关文章
2019年NodeJS框架Koa和Express选型比较
Koa和Express都是NodeJS的主流应用开发框架。
Express是一个完整的nodejs应用框架。Koa是由Express团队开发的,但是它有不同的关注点。Koa致力于核心中间件...WebGL Roadmap
Unity 5.0 shipped with a working preview of our WebGL technology in March this year. Since then, Google has disabled (by default) NPAPI support in the...
React JSX语法简介
JSX是一种类似XML的标签语法,用来简化代码,我们可以不使用JSX,但了解并使用也没什么坏处:)在React中,JSX是一个使用 React.createElement() API的快捷方式...
Web界面编程状态变化和JS开发框架(React/Angular/Ember)
UI编程中的一个关键课题就是界面组件化(可复用)以及组件状态管理。稍早一些的windows程序员可能接触过MFC,其界面编程中有一个DDX(DoDataExchange)的机制,...
CSS3弹性布局弹性流(flex-flow)属性详解和实例
弹性布局是CSS3引入的强大的布局方式,用来替代以前Web开发人员使用的一些复杂而易错hacks方法(如使用float进行类似流式布局)。其中flex-flow是flex-direction...
HTML5动画背后的数学2 - 仿生智能算法综述
WebVR简介和常用资源链接
什么是WebVR这是一个实验性的JavaScript API,提供了在用户网页浏览器中访问虚拟现实设备的统一接口。当前主流VR设备如Oculus Rift DK2、谷歌的CardBoard、三星...
如何使用WebGL实现空气高温热变形动画特效
我们在炎炎夏日,或者在火堆旁,经常会观察到热源周围空气的不稳定波动现象。本文将讲解如何通过WebGL来实现这个特效。该效果可用于热变形、波浪、水面波光等场...
如何实现SVG clipPath自适应被裁剪对象
CSS3中引入的clip-path(裁剪路径)属性是一个很强大的特性。
clip-path的含义如下图所示,好比剪纸一样,你用剪刀沿着某条路径把目标对象(图像或元素)裁...WebGL入门教程4 - 使用纹理贴图(Texture Map)
3D建模和纹理贴图的关系就好比人体和皮肤(或着装)的关系,3D建模用来处理空间属性,而贴图适合用来处理细腻的表面属性。如果不使用贴图,而想在表面达到足够的...
WebGL入门教程1 - 3D绘图基础知识
现代浏览器努力使得Web用户体验更为丰富,而WebGL正处于这样的技术生态系统的中心位置。其应用范围覆盖在线游戏、大数据可视化、计算机辅助设计、虚拟现实以及数...
div 、section 、article的区别和使用场景
div 、section 、article的区别和使用场景
主要区别,以及适用场合如下:
1、div在html早期版本就支持了,section和article是html5提出的两个雨衣话标... 更多...