js闭包的七中形式

Posted 咕咚

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

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

 

以上是关于js闭包的七中形式的主要内容,如果未能解决你的问题,请参考以下文章

从λ演算到函数式编程聊闭包:闭包概念在Java/PHP/JS中形式

JS进阶-闭包的几种常见形式

24 jQuery——对象的封装闭包匿名自调用函数

JavaScript闭包初探

JS高级:闭包

Spark闭包与序列化