美文网首页
简单的聊一下闭包

简单的聊一下闭包

作者: 我爱萨摩耶 | 来源:发表于2017-05-23 00:01 被阅读0次

js中的闭包

闭包是学习js中永远也绕不过去的一个坎,那么,今天我们就去一段简单的代码开始聊一聊闭包

什么是闭包

这个概念性的东西翻译有很多种,纯官方的翻译比较晦涩难懂,我们把它理解成一个比较特殊的函数就行。按照网上的说法来说就是:

「函数」和「函数内部能访问到的变量」(也叫环境)的总和,就是一个闭包。

  function close() {
        var n=999;
        var getNumber=function () {
            return n;
        };
        return getNumber;
    }

在close函数里面有一个getNumber方法,通过getNumber方法可以访问到函数的内部变量。

闭包的特性

  • 能够读取函数内部的变量
  • 能让这些变量的值始终保持在内存中

第一点很好理解,我们平时可能在不知不觉中就使用了闭包的这个特性,而第二点虽然用的不多,但是在面试中经常遇到。首先我们先看一段代码:

 function f1() {
        var n=999;
        nAdd=function () {
            n++;
        };
        function f2() {
            console.log(n);
        }
        return f2;
    }
    var result=f1();
    result();//999
    nAdd();
    result();//1000

为什么第二次执行后打印的结果是1000,而不是999,因为n被保存下来了,并没有被内存回收机制回收。

为什么每有被回收?因为f1是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。

面试题解读

这是一个很常见的闭包面试题:

    var result=[];
    function foo(){
        var i= 0;
        for (;i<3;i=i+1){
            result[i]=function () {
                alert(i);
            }
        }
    }         
    foo();
    result[0](); // 3
    result[1](); // 3
    result[2](); // 3

运行结果为什么是3,我简单的重现一下代码运行的过程,

i=0;
result[0]=function(){alert(i)};
i=1;
result[1]=function(){alert(i)};
i=2;
result[2]=function(){alert(i)};

运行的时候在function内部放的是一个变量i,只有被执行的时候才会给这个i赋值。当执行result[0]的时候,里面的变量i因为在当前作用域下并没有被定义,所以向它的父级去找,此时for循环已经执行完毕,i的值是3,所以弹出的都是3。为什么i保存下来了,因为result函数依赖于foo函数,所以foo一直在内存中,i变量也没有被内存回收机制回收。
那么如何实现弹出的是0,1,2呢?
利用之前提到的闭包就可以了,代码如下:

    var result=[];
    function foo(){
        var i= 0;
        for (;i<3;i=i+1){
            (function () {
                var index=i;
                result[i]=function () {
                    alert(index);
                }
            })()
        }
    }
    foo();
    result[0](); // 0
    result[1](); // 1
    result[2](); // 2

利用立即执行函数(IIF),我们可以创建一个闭包,在这个IIF内部,我们使用index将i给保存下来了。具体执行过程如下:

i=0;
(function () {
    var index=0;
    result[0]=function () {
        alert(index);
    }
})()
i=1;
(function () {
    var index=1;
    result[1]=function () {
        alert(index);
    }
})()
i=2;
(function () {
    var index=2;
    result[2]=function () {
        alert(index);
    }
})()

因为这些语句都放在IIF中,所以都有各自的作用域,index并不会重复。就像下方的代码:

var sayHi=function(){
    var words="hi"
}
var sayHello=function(){
    var words="hello"
}

两个方法中虽然都有words这个变量,但是因为在不同的函数中,都有各自的作用域,所以互不干扰。

参考文献

阮一峰:学习Javascript闭包(Closure)

相关文章

  • 简单的聊一下闭包

    js中的闭包 闭包是学习js中永远也绕不过去的一个坎,那么,今天我们就去一段简单的代码开始聊一聊闭包 什么是闭包 ...

  • 简单聊一下js闭包

    js闭包,阮老师说:‘闭包就是能够读取其他函数内部变量的函数。由于在Javascript语言中,只有函数内部的子函...

  • 浅谈闭包

    js中的闭包 闭包是学习js中永远也绕不过去的一个坎,那么,今天我们就去一段简单的代码开始聊一聊闭包 什么是闭包 ...

  • JS闭包问题(二)

    在之前的JS闭包问题(一)文章中大概介绍了一下JS闭包,同时讲了闭包与变量之间的问题,今天我们继续聊闭包,聊聊闭包...

  • Swift 基本语法(函数, 闭包)

    前言 接上篇, 这篇聊一下 Swift中的 函数, 闭包 一 函数 二 闭包 Swift 基础 先介绍三篇, ...

  • web前端必知篇:闭包的理解

    闭包这玩意,在面试的时候经常被问到。如果你还不了解,小编就简单的讲解一下! 闭包是什么,闭包的优点是什么? 闭包就...

  • Python 闭包使用注意点

    1 Python 闭包 今天,聊下 python 的闭包。在函数编程中经常用到闭包。 闭包是什么,它是怎么产生的及...

  • (9) python之闭包

    闭包闭包 = 函数 + 环境变量(函数定义的时候) 一个最简单的闭包 闭包不受外部变量影响 非闭包 闭包 闭包 只...

  • 2018-12-04

    再次复习一下闭包 什么是闭包? 闭包可以简单理解成“定义在一个函数内部的函数“,有权访问另一个函数作用域内变量的函...

  • 闭包的使用场景,使用闭包需要注意什么

    闭包 什么是闭包 闭包很简单,就是能够访问另一个函数作用域变量的函数,更简单的说,闭包就是函数,只不过是声明在其它...

网友评论

      本文标题:简单的聊一下闭包

      本文链接:https://www.haomeiwen.com/subject/qotwxxtx.html