js中即时函数和闭包的异同?

Herylee
  • 913

在网上看到,即时函数是闭包的特殊例子,但不太清楚它们之间的关联?
各位大神指点下?

回复
阅读 4.3k
13 个回答
✓ 已被采纳

它们并没有必然联系。

即时函数是指定义完了立即调用的匿名函数,往往用它来开辟一个独立的作用域(命名空间)。

当然,如果在即时函数中定义的变量被内部函数捕获的话,那么这个即时函数就形成了一个闭包。例如:

(function() {
    var a = 123;
    button.onclick = function() {
        alert(a);
    };
})();

上面这个例子就是即时函数形成了闭包的情况。

实际上,人们经常用即时函数来构造闭包。为什么呢?因为即时函数只能执行一次,执行完了立马消失,所以不会重复创建闭包,也不会对当前作用域造成任何污染。

所以结论就是:

  • 相同点:他们都是函数的一种特殊形态,并且可以共存。而且闭包配合即时函数“口味更佳”。

  • 不同点:即时函数是定义一个函数,并立即执行。它只能被使用一次,相当于“阅后即焚”。闭包是指一个函数与它捕获的外部变量的合体,按照MDN的说法,闭包就像一个对象---一个具有一个方法(行为)和一个或多个私有字段(状态)的对象。从这个角度看,闭包是符合面向对象的封装思想的。

补充:有些同学认为只要一个函数引用了外部变量,那么就形成了闭包。例如

var a = 'hello';
function fn() {
    console.log(a);
}

甚至有人认为所有函数都是闭包(或具有闭包的能力)。

我觉得这些说法都没有问题。我承认所有函数都有闭包的能力或者捕获外部自由变量的能力。但是我们通常说的闭包是指有用的闭包。所以上面这个例子,就算是个闭包,然而并没有什么用处,所以我们不把它叫闭包。至少它不是个有用的闭包。

闭包是函数自身的特性。他是对内部的变量进行保护,使其不会受到外部的干扰,这是函数的一种机制。
而外部需要使用到函数内部的值就需要用到return。
而你说的即时函数也就是自执行函数。
他是将声明和定义集成到一起操作的,在函数声明定义的时候便开始执行了。
他的确是像你说的,是闭包的一种特殊形式,因为外表看起来是完全包裹的(不知道这个形容词会不会有点2),使得让人会认为这样的形式才是闭包的表现。

  • 闭包:

    var foo = function(){
        //申明一些局部变量
        return function(){//闭包
            // 可以引用这些局部变量
        }
    foo()()//可以对foo函数内的局部变量进行操作,具体方法在闭包函数的定义中
  • 即时函数:

    (function(){})();
  • 不同之处:
    闭包的特点是在外部作用域中可以访问某一个函数的内部变量;
    即时函数的特点一个函数表达式在申明之后立即被执行;

  • 相同之处:
    这个还真不清楚,不知道楼主是在哪里看到这句话的。或者我的理解角度不太对。一起讨论吧。

即时函数不是闭包。
闭包有两个作用,
第一,保存局部变量。
第二,形成私有属性与方法,比如module模式。
即时函数是为了形成块级作用域,来弥补js函数级作用域的局限,主要是为了模块化,很多库都这么来解决耦合。

建议你不要看一些乱七八糟的文章。

立即执行函数是为了解决js没有块级作用域的问题而存在,我认为闭包则是概念。先了解下闭包,再看下两者之间的关系。

1.闭包

闭包是指:在一个函数内部,有能够访问外部作用域中的变量的函数。
特点:即使外部函数执行完毕,由于闭包的存在(引用外部函数的变量),该变量的引用将存在于闭包的作用域里直至闭包销毁。

所以就会出现像下面这个例子那样:
outerFn执行完毕了,但是c函数还是可以访问b变量。

function outerFn() {
    var b = 1;
    return function() {
        b ++;   // 引用外部作用域中的变量
        console.log(b);
    };
}
var c = outerFn();
c();   // 2
c();   // 3
c();   // 4

2.立即执行函数

立即执行函数有多种编写方式,这里就不赘述了。

// 立即执行函数执行完毕之后,在函数外部无法访问内部的局部变量(注意:局部变量)
(function() {
    var a = 1;
}());
console.log(a);  // Uncaught ReferenceError: a is not defined

以上述例子,修改如下:

// 内部函数自执行,也可看出它是个闭包,只是这里内部函数执行完一次后就销毁了。
function outerFn() {
    var b = 1;
    return function() {
        b ++;   // 引用外部作用域中的变量
        console.log(b);
    }();
}
outerFn();

如果lz看完不知道有没有明白些什么。
我也是初学者,哪里说得不好,还望指出(●'◡'●)

1.闭包-函数作用域链
我们知道JS中的变量的作用域在函数内部,那么如果一个函数A定义在另一个函数B的内部,那么在函数A中的定义的变量的作用域还是在函数A内,里面的变量不能被外部函数访问到;但是并不是说在函数A外部定义的变量,也就是函数B中的变量不能够访问,这就是闭包,它为函数A定义了一个作用域,在这个作用域中除了可以访问自身的变量外还可以访问其外层的函数B中的变量,可以一直延展到全局
2.我们在全局作用域下定义的函数都是闭包的-能够访问全局作用域下的变量
3.立即执行函数,顾名思义,就是定义完后马上执行的函数。
一般函数的执行前,必须现在某个地方声明定义好,然后在某个需要的时候调用执行,可以反复调用-只要作用域允许;而立即执行函数在声明定义的时候就被执行了,执行完了以后,我们再也不能利用它了。
3.说有关系么,也是有的 立即执行函数中可以形成闭包

js的闭包是每天1问啊

这两个东西不是包含关系

闭包: 一个函数(无论是不是匿名)持有了定义它的scope中的变量的引用
IIFE: 定义一个匿名函数并立刻执行

口胡,在作用域链和百分百引用传递的js里,哪里有函数!都是闭包!都是闭包!都是闭包!

函数有两种作用,复用和独立(而可以持存)的作用域。当后者是主要目的时,称为闭包。它要么立即执行,要么作为回调函数。此时并不需要变量指向这个函数,也不需要有名字,但也不一定。当没有名字时,称为匿名函数。匿名本身并没有更多的含义,但只有立即执行或回调时才可能匿名,否则无法复用,所以提到匿名函数时往往意味着在提示闭包这一语境。

闭包不是函数,在一个函数的内部访问外部的自由变量即对这个自由变量的闭包,通俗来讲就是捕获变量。

闭包是一种现象。
即时函数是为了模拟 js 没有块级作用域的问题。
如果在即时函数内部引用了一个全局变量,那同样也是形成了一个闭包。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
你知道吗?

宣传栏