常见面试题JavaScript闭包(ES5语法)

techbrood 发表于 2017-01-02 23:05:17

标签: javascript, closure, 基础知识, 常见面试题

- +

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。

你可以自己在线试试看

possitive(5) views9760 comments1

发送私信

最新评论

iefreer 2017-01-02 23:08:28

参阅DC的经典文章:http://www.crockford.com/javascript/private.html


请先 登录 再评论.
相关文章
  • 微信公众号在线生成二维码带参数怎么搞?

    带参数二维码是微信公众号渠道二维码的一种实现
    微信的带参数二维码有两种,一种是临时二维码,一种是永久二维码,但是永久二维码的生成是有个数限制的,微...

  • CentOS6 Apache2.2多站点HTTPS配置

    可以使用letsencrypt(certbot)免费证书服务。支持多系统、多站点和多目录,支持wildcard(通配符域名),90天生效,可用定时任务自动更新。需要注意一点的是apache2.4以下版本需要在默认的ssl配置中添加如下的指令:NameVirtualHost

  • 3D感知和建模关键硬件技术:双目、3D结构光和TOF

    无论VR、AR和3D打印,其核心技术包含3D成像和建模。而3D建模属于劳动密集型的工作,耗时耗力,凡这类工作都会是被新技术革命的地方,自动3D建模技术就是为了解决...

  • OpenGL/WebGL顶点坐标变换过程简介

    世界坐标是按照笛卡尔坐标系定义出来的绝对坐标系,下面的各种坐标系都建立在世界坐标的基础上。对象坐标系对象被应用于任何...

  • 如何使用BabylonJS加载OBJ或STL模型

    BabylonJS(也就是babylon.js,这是一个和three.js类似的WebGL开发框架),更多的用在游戏领域。
    本文说明和演示如何使用babylon.js来加载一个标准3d模型文...

  • A-Frame WebVR(网页虚拟现实)快速开发入门教程

    WebVR和WebGL应用程序接口使得我们已经可以在浏览器上创建虚拟现实(VR)体验,但从工程化的角度而言,开发社区还需要更多方便强大的开发库来简化编程,Mozilla的

  • 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...

  • Three.js入门教程1 - 基础知识和创建一个红色球体

    [ TECHBROOD注:Three.js是一个主流的开源WebGL库,WebGL允许使用JavaScript直接操作GPU,在网页上实现3D效果。
    Google的工程师Paul在网站aerotwist.com上...

  • S3TC(S3 Texture Compression)纹理压缩格式详解

    使用S3TC格式存储的压缩纹理是以4X4的纹理单元块(texel blocks)为基本单位存储的,每纹理单元块(texel blocks)有64bit或者128bit的纹理单元数据(texel data)。这...

  • WebGL入门教程5 - 详解纹理滤镜(Texture Filter)

    WebGL中使用纹理贴图来实现细腻的物体表面观感,其中一个重要的参数是纹理滤镜(Texture Filter)。
    这个参数用来处理当对象出现缩放时,纹理如何处理中间...

  • IE各版本CSS Hack(兼容性处理)语法速查表

    为了兼容IE各个版本,需要在CSS中添加额外的代码,比如以前常用的_width。之所以工作,是因为浏览器会忽略不能解析的样式规则,因此举个例子来说,把_width写在w...

  • WebGL入门教程1 - 3D绘图基础知识

    现代浏览器努力使得Web用户体验更为丰富,而WebGL正处于这样的技术生态系统的中心位置。其应用范围覆盖在线游戏、大数据可视化、计算机辅助设计、虚拟现实以及数...

  • SVG过滤器feColorMatrix矩阵变换效果用法详解

    在计算机图形学(数学)中,矩阵乘法可用于把空间向量进行几何变换。我们可以把颜色的值(RGBA)表示成一个四维空间向量:color = (r, g, b, a);那么就可以应用...

  • 更多...