zoukankan      html  css  js  c++  java
  • 闭包

    一:了解闭包首先要了解嵌套函数的词法作用域规则。

    var scope = "global scope";         /*全局变量*/
    function checkscope() {             
        var scope = "local scope";      /*局部变量*/
        function f() {
            return scope;               /*在作用域中返回这个值*/
        }
        return f();
    }
    console.log(checkscope());           /*"loacl scope*/

    checkscope()函数声明了一个局部变量,并定义了一个函数f(),函数f()返回了这个变量的值,最后将函数f()的执行结果返回。

    改动一下代码,返回什么?

    var scope = "global scope";         /*全局变量*/
    function checkscope() {
        var scope = "local scope";      /*局部变量*/
        function f() {
            return scope;               /*在作用域中返回这个值*/
        }
        return f;
    }
    console.log(checkscope()());          /*返回什么*/

    在这段代码里,将函数内的一对圆括号移动到了checkscope()之后。checkscope()现在仅仅返回函数内嵌套的一个函数对象,而不是直接返回结果。在定义哈数的作用域外部,调用这个嵌套的函数。

    二:实现闭包

    uniqueInteger.counter = 0;
    function uniqueInteger() {
        return uniqueInteger.counter++;
    }
    console.log(uniqueInteger());

    这个函数使用自身的一个属性来保存每次返回的值,以便每次调用都能跟踪上次的返返回值。但是这个做法有个问题,就是恶意代码可能将计数器重置或者把一个非整数付给他,导致函数不一定产生“唯一”的“整数”。而闭包能够捕捉到单个函数调用的局部变量,并将这些局部变量用作私有状态。

    var uniqueInteger = (
        function () {
            var counter = 0;
            return function () {
                return counter++
            };
        }()
    );
    console.log(uniqueInteger());

    这段代码定义了一个立即调用的函数(函数的开始带有左圆括号),因此是这个函数的返回值赋值给变量uniqueInteger。

    这个函数返回另一个函数,这是一个嵌套函数,我们将它赋值给uniqueInteger,嵌套的函数是可以返回作用域内的变量的,而且可以访问外部函数中定义的counter变量。当外部函数返回以后,其他代码都无法访问counter变量,只有内部函数才能访问到他。

    像counter一样的私有变量不是只能用在一个单独的闭包内,在同一个外部函数内定义的多个函数也可以访问它,这与多个嵌套函数都共享一个作用域链。

    function counter() {
        var n = 0;
        return {
            count:function () {
                return n++;
            },
            reset:function () {
                n = 0;
            }
        };
    }
    /*创建2个计数器*/
    var c = counter();
    var d = counter();
    
    console.log(c.count());     /*0*/
    console.log(d.count());     /*0*/
    
    console.log(c.reset());     /*重置了*/
    
    console.log(c.count());     /*0:将c重置了*/
    console.log(d.count());     /*1*/

    counter()函数返回一个“计数器”对象,这个对象包含两个方法:count返回下一个整数,reset将计数器重置为内部状态。首先要理解,这两个方法都可以访问私有变量n。再者,每次调用counter()都会创建一个新的作用域链和一个新的私有变量。因此,如果调用counter()两次,则会得到两个计数器对象,而且彼此包含不同的私有变量,调用其中一个计数器对象的count和reset不会影响到另一个对象。

  • 相关阅读:
    iuplua test failure
    lua C++ wrapper
    lua
    Redux系列01:从一个简单例子了解action、store、reducer
    Meteor入门介绍
    Express入门介绍vs实例讲解
    React半科普文
    Express模版引擎hbs备忘
    Gulp:插件编写入门
    gulp.src()内部实现探究
  • 原文地址:https://www.cnblogs.com/QianBoy/p/7632996.html
Copyright © 2011-2022 走看看