閉包

1. 概念

  1. 閉包是指有權訪問另一個函數作用域中變量的函數
  2. 創建閉包的最常見的方式就是在一個函數內創建另一個函數,當內部函數被保存到外部時,將會生成閉包。
  3. 閉包會導致原有作用域鏈不釋放,造成內存泄漏
  4. 通過另一個函數訪問這個函數的局部變量,利用閉包可以突破作用鏈域,將函數內部的變量和方法傳遞到外部。

2. 閉包的特性

  1. 函數內再嵌套函數
  2. 內部函數可以引用外層的參數和變量
  3. .參數和變量不會被垃圾回收機制回收
function a(){
    function b(){
        console.log(aaa);//123
    }

    var aaa = 123;
    return b;
}
var glob = 100;
var demo = a();
demo();

3. 作用

  1. 實現公有變量,比如累加器
  2. 可以做緩存(存儲結構)
  3. 可以實現封裝,屬性私有化
  4. 模塊化開發,防止污染全局變量

4. 立即執行函數 (主要針對初始化功能的函數)

此類函數沒有聲明,在一次執行過後即釋放,適合做初始化工作。

var num = (function(a,b){
    return a + b
}(1,2))
console.log(num);//3

注意:只有表達式才能被執行符號執行,例:

function a(){
    console.log(123);//報錯 Uncaught SyntaxError: Unexpected token 
}()

function a(){
    console.log(123);//不報錯也不執行
}(1)//穿參的話

var a = function(){
    console.log(123);//123
}()
console.log(a);//undefined,此時函數名將被忽略了
var x= 1;
if(function f(){}){//()爲執行符號,執行完函數就銷燬了,所以typeof f爲undefined
    x += typeof f;
}
console.log(x);//1undefined

5. 經典案例

案例1:
function test(){
    var arr = [];
    for(var i = 0;i < 10;i++){
        arr[i] = function(){//每次循環的時候=的前面依次變成arr[0],arr[1]...arr[9],後面是定義的一個函數,但是沒執行,所以裏面一直都是console.log(i)
            console.log(i)
        }
    }
    return arr
}
var myArr = test();
for(var j = 0;j < myArr.length;j++){
    myArr[j]();//到了此處,上面的函數纔開始執行,而這時候上面的for循環已經結束,退出循環後i變成了10,所以頁面打印出來10次10.
}

如果想輸出0,1,2,3,4,5,6,7,8,9,解決辦法爲:

//方法一:利用函數自執行
function test(){
    var arr = [];
    for(var i = 0;i < 10;i++){
        (function(j){
            arr[j] = function(){
                console.log(j)
            }
        })(i)
    }
    return arr
}
var myArr = test();
for(j = 0;j < myArr.length;j++){
    myArr[j]();
}
//方法:ES6中的let
function test(){
    var arr = [];
    for(let i = 0;i < 10;i++){
        arr[i] = function(){
            console.log(i)
        }
    }
    return arr
}
var myArr = test();
for(var j = 0;j < myArr.length;j++){
    myArr[j]();
}
案例2:不依賴外部變量實現累加器效果
//傳統方法依賴外部變量實現累加器效果
var num = 0;
function a(){
    num++;
    console.log(num);
}
a();//1
a();//2

//不依賴外部變量實現累加器效果
function a(){
    var num = 0;
    function b(){
        num++;
        console.log(num);
    }
    return b;
}
var demo = a();
demo();//1
demo();//2
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章