1. 程式人生 > >再談JavaScript中的閉包

再談JavaScript中的閉包

span 函數作用域 釋放 實現 影響 str ini 代碼 console

一、什麽是閉包

閉包就是有權訪問另一個函數作用域中變量的函數,因此,閉包的本質是一個函數。當一個內部函數被保存到外部時,就會生成閉包。

二、閉包的作用

1、實現公有變量,即通過局部變量實現全局變量的效果

案例:定義一個函數,每調用 一次數字累加一次,即計數器效果

//非閉包實現
var num = 0;
function count() {
    console.log(++num);
}
count(); // 1
count(); // 2
count(); // 3
//閉包實現
function count() {
    var num = 0;
    function
add() { console.log(++num); } return add; } var myCount = count(); myCount(); // 1 myCount(); // 2 myCount(); // 3

2、實現緩存,即多個函數可同時操作一個局部變量

function demo() {
    var fruit = ‘apple‘;
    var obj = {
        eatFruit: function() {
            if (fruit != ‘‘) {
                console.log(
‘eat => ‘ + fruit); fruit = ‘‘; } else { console.log(‘empty‘); } }, pushFruit: function(myFruit) { fruit = myFruit; } } return obj; } var boy = demo(); boy.eatFruit(); // eat => apple
boy.eatFruit(); // empty boy.pushFruit(‘grape‘); boy.eatFruit(); // eat => grape

3、實現封裝屬性私有化

也就是對象無法直接訪問函數內部定義的同級變量,只能通過對象相應的方法來操作變量,仍以上一代碼為例

function demo() {
    var fruit = ‘apple‘;
    var obj = {
        eatFruit: function() {
            if (fruit != ‘‘) {
                console.log(‘eat => ‘ + fruit);
                fruit = ‘‘;
            } else {
                console.log(‘empty‘);
            }
        },
        pushFruit: function(myFruit) {
            fruit = myFruit;
        }
    }
    return obj;
}
var boy = demo();
console.log(boy.fruit); // undefined 

無法通過 對象點變量名 的方式直接訪問變量,只能通過對象內部封裝的方法來操作變量

4、模塊化開發,防止汙染全局變量

var demo = ‘全局內demo‘;

var init = (function(){
    var demo = ‘init局部內demo‘;
    function show() {
        console.log(demo);
    }
    return function() {
        show();
    }
}());

init(); // init局部內demo

var test = (function(){
    var demo = ‘test局部內demo‘;
    function show() {
        console.log(demo);
    }
    return function() {
        show();
    }
}())

test(); // test局部內demo

init和test為獨立模塊,執行 init 和 test 函數後只會輸出內部同名變量,不會影響全局同名變量。

三、閉包的害處

閉包會導致原有作用域鏈不釋放,造成內存泄露,過多閉包會嚴重影響運行速度

再談JavaScript中的閉包