我试着弄明白,闭包是如何工作的,这是我的例子
function func1(func) {
return function(summand) {
return func() + summand;
}
}
var func2 = function() {
return 3;
}
var func3 = func1(func2);
var value = func3(4);
alert(value);
var func2 = function() {
return 100;
}
var newValue = func3(100);
alert(newValue);
首先让我们分解代码。我编写了一个函数,期望作为函数的参数,它将返回一个函数。
function func1(func) {
return function(summand) {
return func() + summand;
}
}
然后我以表达式形式
定义了参数函数func2var func2 = function() {
return 3;
}
然后调用func1并将func2作为pamerater。结果我有一个功能回来
var func3 = func1(func2);
然后我执行函数并传递4作为参数参数
var value = func3(4);
结果我得到7.然后我覆盖func2并返回100
var func2 = function() {
return 100;
}
然后再次调用func3并作为参数值100传递。
var newValue = func3(100);
结果我得到了103.我定义的第一个函数(返回一个函数并将函数作为参数)仍将使用第一个版本的func2。关闭的力量,我知道。
但是看看下面的代码,当我将func2定义为函数声明而不是表达式时,那么func2将覆盖
function func1(func) {
return function(summand) {
return func() + summand;
}
}
function func2() {
return 3;
}
var func3 = func1(func2);
var value = func3(4);
alert(value);
function func2() {
return 100;
}
var newValue = func3(100);
alert(newValue);
第一个值是104,第二个值是200 我的问题是,为什么当我使用函数声明时它会覆盖旧函数,在这个例子中是func2。但是当我使用函数表达式时,它将保留对旧func2的引用 那是因为功能提升?
答案 0 :(得分:4)
这不是因为关闭。
就像你想的那样 - 这个问题是因为功能提升。
您可以将函数声明视为“向上移动”到当前范围的开头。
var f2 = function(){
return 50;
}
function f2(){
return 100;
}
在这种情况下,f2为50,因为它的解析方式类似于:
var f2 = function(){
return 100;
}
var f2 = function(){
return 50;
}
因为悬挂。
答案 1 :(得分:3)
因为吊装而 。使用function
statement而不是function
expression会导致函数func2
被提升到范围的顶部。在执行范围中的任何代码之前,您将覆盖func2
。
因为提升你的代码实际上是这样的:
function func1(func) {
return function(summand) {
return func() + summand;
}
}
function func2() {
return 3;
}
// Hoisted!!! Overwriting the previous func2 definition.
function func2() {
return 100;
}
var func3 = func1(func2);
var value = func3(4);
alert(value);
var newValue = func3(100);
alert(newValue);
在func1
内,func
是对其传递的函数的稳定引用...只是在您认为自己之前传递return 100;
版本。
答案 2 :(得分:1)
使用function foo() { ... }
样式时,您正在定义名为foo
的函数。当您使用var foo = function() { ... }
样式时,您声明变量foo
(将被提升),并将匿名函数指定为其值。
可以写
var a;
a = 2;
// ...stuff...
a = 3;
我们希望该值为3.所以就在这里,吊装就是这样:
var func2;
func2 = function() { .. some stuff.. };
// ...stuff...
func2 = function() { .. some other stuff .. };
相比之下,我认为如果你定义函数,它只会在初始解析中采用一个或其他函数定义。