我对Javascript相对较新。我理解匿名函数的概念 - 但是闭包似乎不太清楚。两者之间的相似性(至少在我看来)是令人困惑的。
有人可以解释一下这个区别吗? (最好用一些代码片段来说明这些要点更清楚)。
答案 0 :(得分:7)
重要的区别在于闭包捕获了它所定义的范围。
换句话说,闭包可以访问变量及其状态,即使它们属于闭包的父作用域(例如,闭包创建的函数)。这允许闭包捕获并“传输”程序周围的应用程序状态。
匿名函数不能这样做;它的范围仅限于在其身体和特征(即其参数)内定义的变量。
编辑:只是为了澄清:在JavaScript中,由于没有称为闭包的语言结构,因此特别不清楚。你仍然会使用匿名函数。我只是指概念差异。
答案 1 :(得分:6)
这也可以作为起点:http://www.javascriptkit.com/javatutors/closures.shtml
答案 2 :(得分:2)
答案 3 :(得分:0)
我找到了这个答案,这对我来说非常清楚:
答案 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创建多个引用。