任何人都可以解释闭包和匿名函数之间的区别吗?

时间:2010-01-25 09:12:29

标签: javascript

我对Javascript相对较新。我理解匿名函数的概念 - 但是闭包似乎不太清楚。两者之间的相似性(至少在我看来)是令人困惑的。

有人可以解释一下这个区别吗? (最好用一些代码片段来说明这些要点更清楚)。

5 个答案:

答案 0 :(得分:7)

重要的区别在于闭包捕获了它所定义的范围。

换句话说,闭包可以访问变量及其状态,即使它们属于闭包的父作用域(例如,闭包创建的函数)。这允许闭包捕获并“传输”程序周围的应用程序状态。

匿名函数不能这样做;它的范围仅限于在其身体和特征(即其参数)内定义的变量。

编辑:只是为了澄清:在JavaScript中,由于没有称为闭包的语言结构,因此特别不清楚。你仍然会使用匿名函数。我只是指概念差异。

答案 1 :(得分:6)

答案 2 :(得分:2)

我在这里解释了这一点:The Zen of Closures

基本上,没有进入技术细节:

  • 匿名函数是没有名称的函数(可以分配给变量)。
  • 闭包是一种私有全局变量

答案 3 :(得分:0)

我找到了这个答案,这对我来说非常清楚:

Does Java need closures?

答案 4 :(得分:0)

匿名函数是一个没有名称的函数,其余部分与Javascript中的常规函数​​相同。 这是前 情况1: 这只是一些普通/常规的javascript函数

var sayHello = function iWillSayHello(name){
     var fullName = "Hello, " + name; 
     console.log(fullName);
}
sayHello("ABC");    // prints--->  Hello, ABC

情况2: 这是匿名功能, 它具有与上述相同的功能,并且具有相同的行为,

var sayHello = function(name){
     var fullName = "Hello, " + name; 
     console.log(fullName);
}
sayHello("ABC");    // prints--->  Hello, ABC

情况3: 如果(我认为)“匿名函数”是指IIFE(立即调用函数执行), 就是这个,

(function(name){
     var fullName = "Hello, " + name; 
     console.log(fullName);
})();     // prints--->  Hello, ABC

这里的区别是,在“案例1”和“案例2”中,您必须显式调用该函数,但是在“案例3”中,它会自动被调用(即,在您调用它的末尾使用“()”)声明)。 当编译器到达该行时,它将被调用。

另一方面,

修饰符是一个函数内部的一个函数。 Clouser在js中的特殊之处在于,即使外部函数已返回,它仍然可以从外部函数的“本地范围” 访问变量的值。

Clouser =函数+外部上下文

这是一个简单的例子,

function outerSayHello(firstName){
    var fullName = firstName;
    function innerSayHello(lastName){
         console.log("Hello, ", fullName + " " + lastName);
    }

    return innerSayHello;
}

console.log("1-------------------------");
var sayHello = outerSayHello("A");
sayHello("B");
//Hello,  A B

console.log("2-------------------------");
var sayHello1 = outerSayHello("A1");
sayHello1("B1");
//Hello,  A1 B1

console.log("3-------------------------");
sayHello("b");
//Hello,  A b

console.log("4-------------------------");
sayHello1("b1");
//Hello,  A1 b1

console.log("5-------------------------");
outerSayHello("ABC")("XYZ");
//Hello,  ABC XYZ

to better understand these let's console the sayHello variable

console.log("6-------------------------",sayHello);
/*
  innerSayHello(lastName){
         console.log("Hello, ", fullName + " " + lastName);
    }
*/

这意味着 sayHello 变量具有 innerSayHello 函数的指针/引用。 而且,由于 innerSayHello 依赖于 fullName 变量,因此仍将其保留在堆上,甚至在之后,fullName和 innerSayHello 仍将位于堆栈上 outerSayHello 返回。 因此,在堆中,它将为全名和innerSayHello创建多个引用。