通过示例彻底搞懂js闭包

 更新时间:2017年08月10日 08:04:59   投稿:jingxian  
下面小编就为大家带来一篇通过示例彻底搞懂js闭包。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

例1

function sayHello(name) 
{
 var text = 'Hello ' + name;
 var sayAlert = function() { console.log(text); }
 sayAlert();
}

sayHello("Bob") // 输出"Hello Bob"

在sayHello()函数中定义并调用了sayAlert()函数;sayAlert()作为内层函数,可以访问外层函数sayHello()中的text变量。

例2

function sayHello2(name) 
{
 var text = 'Hello ' + name; // 局部变量
 var sayAlert = function() { console.log(text); }
 return sayAlert;
}

var say2 = sayHello2("Jane");
say2(); // 输出"Hello Jane"

例3

function buildList(list) {
 var result = [];
 for(var i = 0; i < list.length; i++) {
  var item = 'item' + list[i];
  result.push( 
    function() {
      console.log(item + ' ' + list[i]);
    } 
   );
 }
 return result;
}

var fnlist = buildList([1,2,3]);
for (var j = 0; j < fnlist.length; j++) {
  fnlist[j](); 
}

得到的结果:连续输出3个"item3 undefined"

解析:通过执行buildList函数,返回了一个result,那么这个result存放的是3个匿名函数。然而这三个匿名函数其实就是三个闭包,因为它可以访问到父函数的局部变量。所以闭包内的保留的i是最终的值为3.所以list[3]肯定是undefined. item变量值为item3.

改成如下代码:

function buildList(list) {
 var result = [];
 for(var i = 0; i < list.length; i++) {
  var item = 'item' + list[i];
  result.push( 
    (function(i) {
      console.log(item + ' ' + list[i]);
    })(i)
   );
 }
 return result;
}

var fnlist = buildList([1,2,3]);

得到的结果:

item1 1
item2 2
item3 3

解释:这儿虽然传递了一个数组进去,但是返回的是三个自执行的函数。

例4

function newClosure(someNum, someRef) 
{
 var anArray = [1,2,3];
 var num = someNum;
 var ref = someRef;
 return function(x) 
 {
 num += x;
 anArray.push(num);
 console.log('num: ' + num + "; " + 'anArray ' + anArray.toString() + "; " + 'ref.someVar ' + ref.someVar);
 }
}
closure1 = newClosure(40, {someVar: "closure 1"}); 
closure2 = newClosure(1000, {someVar: "closure 2"}); 
closure1(5); // 打印"num: 45; anArray 1,2,3,45; ref.someVar closure 1"
closure2(-10); // 打印"num: 990; anArray 1,2,3,990; ref.someVar closure 2"

每次调用newClosure()都会创建独立的闭包,它们的局部变量num与ref的值并不相同。

例5

function sayAlice() 
{
 var sayAlert = function() { console.log(alice); }
 var alice = 'Hello Alice';
 return sayAlert;
}

var sayAlice2 = sayAlice();
sayAlice2(); // 输出"Hello Alice"

alice变量在sayAlert函数之后定义,这并未影响代码执行。因为返回函数sayAlice2所指向的闭包会包含sayAlice()函数中的所有局部变量,这自然包括了alice变量,因此可以正常打印”Hello Alice”。

例6

function setupSomeGlobals() {
 var num = 666;
 gAlertNumber = function() { console.log(num); }
 gIncreaseNumber = function() { num++; }
 gSetNumber = function(x) { num = x; }
}
setupSomeGlobals();
gAlertNumber(); // 输出666
gIncreaseNumber();
gAlertNumber(); // 输出667
gSetNumber(5);
gAlertNumber(); // 输出5

解释:首先gAlertNumber,gIncreaseNumber,gSetNumber是三个全局变量,并且其三个值都是匿名函数,然而这三个匿名函数本身都是闭包。他们操作的num都是保存在内存中的同一个num,所有会得出上面的结果。

以上这篇通过示例彻底搞懂js闭包就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • JS类型判断的四种方法详解

    JS类型判断的四种方法详解

    JavaScript中有七种原始数据类型和几种引用数据类型,本文将清楚地介绍四种用于类型判断的方法,分别是typeOf、instanceOf、Object.prototype.toString.call()、Array.isArray(),并介绍其使用方法和判定原理,需要的朋友可以参考下
    2024-08-08
  • 老生常谈JavaScript 函数表达式

    老生常谈JavaScript 函数表达式

    下面小编就为大家带来一篇老生常谈JavaScript 函数表达式。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-09-09
  • js动态添加onload、onresize、onscroll事件(另类方法)

    js动态添加onload、onresize、onscroll事件(另类方法)

    window 的 onload、onresize、onscroll 事件,跟其他的事件不一样,它不能用 attachEvent 或 addEventListener 来添加于是本人想了一些另类的方法,需要了解的朋友可以参考下
    2012-12-12
  • JS Array创建及concat()split()slice()的使用方法

    JS Array创建及concat()split()slice()的使用方法

    下面小编就为大家带来一篇JS Array创建及concat()split()slice()的使用方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-06-06
  • js处理json以及字符串的比较等常用操作

    js处理json以及字符串的比较等常用操作

    js处理json格式的插入、修改、删除,以及字符串的比较等常用操作,下面有五个示例,感兴趣的朋友可以学习下
    2013-09-09
  • JavaScript 中的行继续符操作

    JavaScript 中的行继续符操作

    JavaScript 中的字符串操作可能很复杂, 尽管字符串操作易于掌握,但实施起来却具有挑战性,其中一个相关领域是添加新行,这篇文章主要介绍了JavaScript中的行继续符操作,需要的朋友可以参考下
    2023-06-06
  • js图片上传中file、bolb、base64图片之间的相互转化

    js图片上传中file、bolb、base64图片之间的相互转化

    这篇文章主要介绍了js图片上传中file、bolb、base64图片之间的相互转化,blob转file,blob转base64,base64转file,使用canvas压缩图片,需要的朋友可以参考下
    2022-05-05
  • 微信小程序HTTP请求从0到1封装

    微信小程序HTTP请求从0到1封装

    这篇文章主要给大家介绍了关于微信小程序HTTP请求从0到1封装的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用微信小程序具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-09-09
  • Bootstrap学习笔记之css组件(3)

    Bootstrap学习笔记之css组件(3)

    这篇文章主要为大家详细介绍了bootstrap学习笔记中的css组件,感兴趣的小伙伴们可以参考一下
    2016-06-06
  • javascript实现贪吃蛇小练习

    javascript实现贪吃蛇小练习

    这篇文章主要为大家详细介绍了javascript实现贪吃蛇的小练习,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-07-07

最新评论