天天看點

【js前端面試】閉包/閉包的作用

什麼是閉包

如果内層函數使用了外層函數中定義的局部變量,并且外層函數的傳回值是内層函數的引用,就構成了閉包。

閉包可以讓我們在一個内層函數中通路到外層函數的作用域。

在js中,每當建立一個函數,閉包就會在函數建立的同時被建立出來,作為函數内部與外部連接配接起來的一個橋梁。

下面是一個計數器(閉包)的例子:

1>在初始化c的時候,add()方法執行一次,但是沒有執行plus,最終傳回plus函數。

2>第一次調用c(),閉包函數plus()第一次執行,counter+1,值為1.

3>第二次調用c(),閉包函數plus()第二次執行,counter再次+1,值為2

//實作計數器
function add(){
    var counter = 0;
    function plus(){
        counter += 1;
        console.log(counter);
    }
    //這裡的傳回值不加()
    return plus;
}
var c = add();      //這裡plus沒有執行
c();
c();
//最終輸出1 2
           

還有當頻繁調用具有相同參數的函數時,使用閉包可以進行重用。

比如我們計算長方形的面積,一般的寫法如下:

function area(width,height){
    return width*height;
}
area(10,2);
area(10,3);
           

但是當我們多次使用width=10來計算時,可以使用閉包來避免相同參數的頻繁調用:

//使用閉包求長方形面積
function solve(width){
    function area(height){
        return width*height;
    }
    return area;
}
var a = solve(10);
console.log(a(2));		//20
console.log(a(3));		//30
           

閉包的作用

閉包常常用來間接通路一個變量,或者隐藏變量。(全局變量能通過閉包實作局部私有)

在js中,沒有聲明私有變量的方法,這時可以通過閉包來完成。

還是計數器的例子,我們聲明兩個計數器c和d:

其中c和d是維護他們各自獨立性的,每次調用其中一個計數器時,會改變這個閉包的詞法環境,但是不會影響另一個閉包中的變量。

//實作計數器
function add(){
    var counter = 0;
    function plus(){
        counter += 1;
        console.log(counter);
    }
    //這裡的傳回值不加()
    return plus;
}
var c = add();      //這裡plus沒有執行
c();      //1
c();      //2
var d = add();
d();      //1   c計數器不會改變d計數器
           

閉包主要用在計數器、延遲調用、回調等。

核心思想是建立私有變量、延遲變量的生命周期。

繼續閱讀