1. 程式人生 > >js閉包的七中形式

js閉包的七中形式

col erro turn 外部變量 閉包 累加 聲明 cal 函數賦值

要深入了解閉包,並不簡單;

最常用的一種形式是函數作為返回值被返回

var F = function(){
    var b = ‘local‘;
    var N = function(){
        return b;
    }
    return N;
}
console.log(F()());

函數賦值

  一種變形的形式是將內部函數賦值給一個外部變量

var inner;
var F = function(){
    var b = ‘local‘;
    var N = function(){
        return b;
    };
    inner 
= N; }; F(); console.log(inner());

函數參數

  閉包可以通過函數參數傳遞函數的形式來實現

var Inner = function(fn){
    console.log(fn());
}
var F = function(){
    var b = ‘local‘;
    var N = function(){
        return b;
    }
    Inner(N);
}
F();

其實上面三種的寫法,有種換湯不換藥的感覺;

function Inner(fn){
    console.log(fn());
}

(function
(){ var b = ‘local‘; var N = function(){ return b; } Inner(N); })();

g(s)etter

  我們通過提供getter()和setter()函數來將要操作的變量保存在函數內部,防止其暴露在外部

var getValue,setValue;
(function(){
    var secret = 0;
    getValue = function(){
        return secret;
    }
    setValue = function(v){
        
if(typeof v === ‘number‘){ secret = v; } } })(); console.log(getValue());//0 setValue(1); console.log(getValue());//1

叠代器

  我們經常使用閉包來實現一個累加器

var add = (function(){
    var counter = 0;
    return function(){
        return ++counter; 
    }
})();
console.log(add())//1
console.log(add())//2  

關於閉包的定義:這個是比較多滴呀;

古老定義

  閉包(closure),是指函數變量可以保存在函數作用域內,因此看起來是函數將變量“包裹”了起

那這樣說來,包含變量的函數就是閉包

//按照古老定義,包含變量n的函數foo就是閉包
function foo() {
    var n = 0;
}
console.log(n)//Uncaught ReferenceError: n is not defined
 

閉包是指可以訪問其所在作用域的函數

  那這樣說來,需要通過作用域鏈查找變量的函數就是閉包

//按照定義二的說法,嵌套在foo函數裏的bar函數就是閉包
function foo(){
    var a = 2;
    function bar(){
        console.log(a); // 2
    }
    bar();
}
foo();

定義三(這個最常見滴呀)

  閉包是指在函數聲明時的作用域以外的地方被調用的函數

  在函數聲明時的作用域以外的地方調用函數,需要通過將該函數作為返回值或者作為參數被傳遞

function foo(){
    var a = 2;
    return function(){
        console.log(a);//2
    }
}
foo()();

IIFE是不是閉包呢?

  foo()函數在全局作用域定義,也在全局作用域被立即調用,如果按照定義一的說法來說,它是閉包。如果按照定義二和定義三的說法,它又不是閉包

var a = 2;
(function foo(){
    console.log(a);//2
})();

嚴格來說,閉包需要滿足三個條件:【1】訪問所在作用域;【2】函數嵌套;【3】在所在作用域外被調用

  有些人覺得只滿足條件1就可以,所以IIFE是閉包;有些人覺得滿足條件1和2才可以,所以被嵌套的函數才是閉包;有些人覺得3個條件都滿足才可以,所以在作用域以外的地方被調用的函數才是閉包

  問題是,誰是權威呢?

其實閉包的本質是作用域的問題,變量的生存依賴作用域,變量或引用之前的循環嵌套,導致作用域之間依賴......這樣說起起來很抽象,具體還得開實例,比如我的這邊文章:http://www.cnblogs.com/mc67/p/4801422.html

具備實現閉包的條件和是否是閉包,這個我們得區分開;

js閉包的七中形式