[英]Javascript closure overwrite function expression
我試着弄明白,封閉是如何工作的,這是我的榜樣
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;
}
}
然后我以表達式的形式定義了參數函數func2
var 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的引用。
那是因為功能提升?
這不是因為關閉。
就像你想出的那樣 - 這個問題是因為功能提升 。
您可以將函數聲明視為“向上移動”到當前作用域的開頭。
var f2 = function(){
return 50;
}
function f2(){
return 100;
}
在這種情況下,f2為50,因為它的解析方式類似於:
var f2 = function(){
return 100;
}
var f2 = function(){
return 50;
}
因為吊裝。
這是因為吊裝。 使用function
語句而不是function
表達式會導致函數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;
在您認為自己之前的版本。
當您使用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 .. };
相比之下,我認為如果你定義函數,它將只在初始解析中采用一個或其他函數定義。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.