JavaScript 经典之一 闭包

Posted 小小坤

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript 经典之一 闭包相关的知识,希望对你有一定的参考价值。

作为一个前端开发者,闭包是必须要攻克掉的障碍。据说好多面试者挂在闭包面试上。下面我就给大家讲一下我理解中的闭包。不说太多的废话,直接进入主题。

变量作用域

学习编程语言需要明白,变量的作用域。变量作用域分全局变量、局部变量。全局变量尽量少用,因为它很耗费性能。简单理解,全局变量:在任何一个地方都可以访问到。局部变量只有在局部才可以访问到。先举个例子看看:

var data=100;
function domo(){
    var data1=20;
    console.log(data);
    console.log(data1);
}
domo();

可以看出data在dome中也可被访问。所有呢!data是全局变量,data1是局部变量。

闭包

1.常见闭包

/**
 * 最简单的闭包
 * */
function bibao(){
    var d=10;
    return function(){
        console.log(d);
        d++;
    }
}
var _bibao=bibao();
_bibao();//输出10
_bibao();//输出11

  首先我们要明白函数是有返回值的,如果不手动更改返回值则返回undefined。如何手动更改返回值?就是在函数中使用return 返回。可以返回为布尔值也可以是对象也可以是空字符串也可以是函数。这个最简单的闭包就是返回一个匿名函数。_bibao接收到bibao函数的返回。相当于_bibao===function(){console.log(d);d++;}。然而这个匿名函数中用到了d。此刻_bibao就可以访问d;也可以更改d

 

   2.无return闭包

  1. /**
     * 无return的闭包
     * 
     * */
    var _bibao1;
    function bibao1(){
        var d=20;
        _bibao1= function(){
            console.log(d);
            d++;
        }
    }
    bibao1();
    _bibao1();//输出20
    _bibao1();//输出21
    
    

这种没有return 的闭包其实跟上面最简单的闭包是相同的,它只不过把一个匿名函数赋值给全局变量。全局变量此刻保持对这个匿名函数的引用。当调用_bibao1()的时候,就等于调用这个匿名函数。

3.回掉函数中产生的闭包

/**
 * 回掉函数中产生的闭包
 * @callback {Function} 回掉函数
 * */

function bibao2(callback){
    var d=100;
    setTimeout(function(){
        callback()
    },2000)
}

function _bibao2(){
    var d=120;
    bibao2(function(){
        console.log(d);
        d++;
    });
    setTimeout(function(){
        console.log(d);
    },3000)
}
_bibao2();//两秒后输出120。三秒后输出121

只有记住一个变量或者参数是一个函数的引用,这个答案就会迎刃而解。执行_bibao2();它会执行bibao2,然后传入一个匿名函数,此刻这个匿名函数保持可以访问到_bibao2中的d。bibao2中的参数callback保持对这个匿名函数的引用。所以它访问的是_bibao2中的d而不是bibao2中的d。

总结

   闭包是很有用的,也是很常用的,只有我们记住了它的原理,就能够掌控它们。它只不过是一个函数的引用,这个函数可以访问到这个函数的父函数中的变量而已。

 

以上是关于JavaScript 经典之一 闭包的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript闭包的9大经典使用场景

闭包——JavaScript 中功能最强大的抽象概念之一

JS---闭包

几个关于js数组方法reduce的经典片段

几个关于js数组方法reduce的经典片段

JavaScript中无处不在的闭包