js闭包的七中形式

javascript 是一门很神奇的语言,真的,

要深入了解闭包,并不简单;

最常用的一种形式是函数作为返回值被返回

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

具备实现闭包的条件和是否是闭包,这个我们得区分开;

原文地址:https://www.cnblogs.com/mc67/p/6882836.html