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

iefreer 发表于 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(0) negative(0) views2613 comments1
私信 收藏 分享
分享到

发送私信

最新评论

iefreer 2017-01-02 23:08:28

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


请先 登录 再评论.
相关文章
  • HTML5 And Canvas 2D Specs Are Now Feature Complete, First HTML 5.1 Working Draft Published

    We’ve been writing about HTML5 for quite a while, but, until today, the actual HTML5 specs and standards were still moving targets. Now, however, the...

  • WebGL、Asm.js和WebAssembly概念简介

    随着HTML技术的发展,网页要解决的问题已经远不止是简单的文本信息,而包括了更多的高性能图像处理和3D渲染方面。这正是要引入WebGL、Asm.js和WebAssembly这些技...

  • 使用CSS3 box-decoration-break特性实现多行文本样式

    当文章中的长文本被自动断行为多行文本时,其样式可能会出乎我们的设计。本文介绍如何使用CSS3中的box-decoration-break特性来处理多行元素样式。
    按照规范...

  • NodeJS、Java和PHP性能考量和若干参考结论

    首先需要说明的是,严格而言NodeJS和Java、PHP并非对等概念,NodeJS是基于JS的一个应用程序,而Java/PHP是语言。我们这里实际指的是分别使用node、java和php来实...

  • 深入理解CSS3滤镜(filter)功能和实例详解

    CSS3滤镜功能源自SVG滤镜规范,SVG滤镜最早用来给矢量图添加类似PS中像素图的一些特效。
    把这个滤镜功能引入到普通HTML元素中可以带来很有趣的效果(模糊、...

  • Three.js入门教程4 - 创建粒子系统动画

    嗨,又见面了。这么说我们已经开始学习Three.js了,如果你还没有看过之前三篇教程,建议你先读完。如果你已经读完前面的教程了,你可能会想做一些关于粒子的东西。让我们直面这个话题吧,每个人都爱粒子效果。不管你是否知道,你可以很轻易地创建它们。

  • WebGL入门教程4 - 使用纹理贴图(Texture Map)

    3D建模和纹理贴图的关系就好比人体和皮肤(或着装)的关系,3D建模用来处理空间属性,而贴图适合用来处理细腻的表面属性。如果不使用贴图,而想在表面达到足够的...

  • 使用Canvas绘制完美的不完美圆形

    真实世界是不完美的,当我们需要模拟真实世界时,经常需要引入不完美/不规则的形状。比如陨石、雨滴、行星、树叶、绵延的海岸线、云朵等。本文介绍如何基于Canva...

  • 如何使用CSS3实现一个平滑的3D文本标题

    要实现3D文本,基本上有3种方法:1. 使用CSS3的投影滤镜(filter: drop-shadow)2. 使用3d建模和CSS3 3d变换来实现(最真实)3. 使用CSS3 text-shadow属性来实现...

  • 如何使用CSS3/SCSS实现逼真的车窗雨滴效果

    在天气预报类的Web移动应用中,常常需要实现屏幕的雨滴效果,表示阴雨天气。感觉上比较神奇,其实想通了,这个效果的实现只需要一点物理知识和CSS3的简单变换。实现一个小雨滴首先雨滴是一个个小的椭圆形元素:.raindrop

  • 更多...