立即执行函数和闭包有什么关系

匿名闭包

匿名闭包是很常用的代码隔离方式,声明匿名对象并立即执行。匿名函数中声明的变量和方法以及匿名函数本身不会污染到函数体外,同时匿名函数的调用形成一个闭包,使函数体内可以使用函数体外声明的变量和方法。

(function () {
    // ... all vars and functions are in this scope only
    // still maintains access to all globals
}());

今天看了一个文章 原文 http://web.jobbole.com/85883/

这个立即执行函数 和闭包有什么关系呢
是立即执行函数中包含一个全局作用域中的一个函数的引用 所以就形成了闭包么?这么理解对么
还是说文中的解释 是错误的?

阅读 14.2k
6 个回答

匿名函数和闭包没有直接关系。能用匿名函数实现闭包的地方,一定也能用命名函数实现。

闭包的本质在于“闭”和“包”,即把一些变量封闭起来,使其它程序访问不到,同时把这个封闭的东西打成包甩出来,让大家可以直接用这个包(函数)。最典型的实现之一是对象(或类)的私有成员,如

function MyClass() {
    // 这是一个封闭在 MyClass 中的局部变量
    var _name;
    
    // 这是一个甩出来的“包”
    this.getName = function() {
        return _name;
    };
    
    // 这是另一个甩出来的“包”
    this.setName = function(name) {
        // 这保证了 _name 的第一个字母和空格后的第一个字母是大写
        // 而且因为闭包的原因,_name 不可能被 MyCLass() 外的程序访问到
        // 也就保证了上述命名规则的无例外执行
        _name = name.replace(/^.|\s./g, function(s) {
            return s.toUpperCase();
        });
    };
}

var p = new MyClass();
p.setName("james fancy");
console.log(p.getName());   // James Fancy

匿名函数通常只是用于给成员赋值,比如上例中的 getNamesetName;也有可能用于立即执行函数,比如你的那段代码,这会将全局变量局部化,避免全局污染。

闭包常常会和匿名函数一起使用,但他们之间并没有密不可分的关系。

立即执行函数只是函数的一种调用方式,和闭包没有必然的联系

(function(){
....
}());

可以拆解为

function a(){
...
}
a();

闭包是对函数中变量作用域的构成方式的一种表述,具体表现为一个函数中可以访问不在其作用域范围内但在其外层函数作用域中存在的变量,这个外层函数作用域的顶层为全局作用域

需要注意的一点是:闭包不等于匿名函数。
创建闭包的方式通常是在一个函数的内部创建另一个函数。
创建闭包的目的是通过返回函数来扩大函数的作用域。

IIFE主要目的是做的一些封装,防止污染,以及保证内部变量的安全

闭包严格来说,是一个函数执行之后,返回另外一个函数,返回的函数有前一个函数的内部变量的引用

可能会用在IIFE里面,通过返回的函数来提供内部变量的一些操作

新手上路,请多包涵

匿名函数从字面理解就是没有命名的函数,如:

function() {
  //...
}

立即执行函数是指声明完之后便直接执行的函数,因此通常这类函数也不需要命名,如:

(function() {
  //...
})();

闭包通常指在函数内部再定义一个函数,由于作用域的关系,外部函数无法访问内部函数的变量,而内部函数可以访问外部函数的变量,此时如果外部函数将内部函数返回,便形成了闭包,如:

function outer() {
  var prop = 'outer';
  function inner() {
    console.log(prop); // outer
  }
  return inner;
}

所以,也可以把任何函数理解为一个闭包,因为每个函数都可以访问外部函数或者全局的变量,但是外部函数或全局无法访问函数内部的变量,也就可以理解为是一个闭包。

没什么关系,大多写库或框架的时候为了避免全局冲突会使用闭包,为了库或函数的功能加载后就可以使用就使用立即执行的方式将库注册到全局。

推荐问题
宣传栏