常见面试题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。
你可以自己在线试试看。


- 相关文章
Blender2.7给平面模型添加纹理贴图
在blender中给模型添加纹理,需要有2个步骤:首先在对象属性栏中给该对象添加材料和纹理建立纹理映射添加材料和纹理这是常见操作,略过步骤。但是仅仅这样操作,...
CSS3属性选择器特性使用详解
CSS3除了引入动画、滤镜(用于特效)以及新的布局技术外,在选择器(selector)方面也有增强。属性选择器根据元素的属性(attributes)来匹配。这可以是一个单独...
React JSX语法简介
JSX是一种类似XML的标签语法,用来简化代码,我们可以不使用JSX,但了解并使用也没什么坏处:)在React中,JSX是一个使用 React.createElement() API的快捷方式...
JavaScript语言多编程范式简介
和C++等语言类似,JS支持多范式(paradigms)编程。我们常常混合这些范式来完成一些大型Web项目。JS支持3种编程范式:命令式、面向对象和函数式。命令式(Imperative JavaScript)命令式就是简单的从上而下完成任务,流水账过程式编码风格:function
HTML5动画背后的数学2 - 仿生智能算法综述
Babylon.js入门教程和开发实例
Babylon.js是一款WebGL开发框架。和Three.js类似。主要的技术区别是Three.js还试图回退兼容CSS 3D。Three.js是完全社区推动的,比Babylon.js要成熟些,而Babylon...
粒子运动模拟 - Verlet积分算法简介
Verlet算法是经典力学(牛顿力学)中的一种最为普遍的积分方法,被广泛运用在分子运动模拟(Molecular Dynamics Simulation),行星运动以及织物变形模拟等领域...
WebGL 纹理映射模式以及WRAP_S | WRAP_T参数详解
我们在纹理滤镜一文中已经说明了2个重要的纹理参数,用来定义对象缩放时纹理的处理方式:GL_TEXTURE_MIN_FILTERGL_TEXTURE_MAG_FILTER本文讲解其余几个纹理参数...
Three.js入门教程4 - 创建粒子系统动画
嗨,又见面了。这么说我们已经开始学习Three.js了,如果你还没有看过之前三篇教程,建议你先读完。如果你已经读完前面的教程了,你可能会想做一些关于粒子的东西。让我们直面这个话题吧,每个人都爱粒子效果。不管你是否知道,你可以很轻易地创建它们。
Three.js入门教程1 - 基础知识和创建一个红色球体
[ TECHBROOD注:Three.js是一个主流的开源WebGL库,WebGL允许使用JavaScript直接操作GPU,在网页上实现3D效果。
Google的工程师Paul在网站aerotwist.com上...WebGL入门教程5 - 详解纹理滤镜(Texture Filter)
WebGL中使用纹理贴图来实现细腻的物体表面观感,其中一个重要的参数是纹理滤镜(Texture Filter)。
这个参数用来处理当对象出现缩放时,纹理如何处理中间...如何基于Canvas来模拟真实雨景Part2:重力掉落和雨滴融合
如何基于Canvas来模拟真实雨景Part1:预备知识和创建基本对象
使用CSS3实现流星雨动画教程
很多营销页面中需要实现类似流星雨的动画背景,营造节日浪漫的气氛。要实现这样的效果,有两种方法,一个是使用Canvas,一个是使用纯CSS3,我们这里介绍第2种方...
更多...