簡體   English   中英

Javascript閉包覆蓋函數表達式

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM