2017-05-31 28 views
0

Javascript支持First Class Functions,在這種情況下,我們可以將該函數作爲參數傳遞。在另一個函數的參數列表中定義的匿名函數,該匿名函數的詞法環境(即範圍)是什麼?函數參數的詞法環境是什麼?

例如:

var m = 2; 

(function(p1,p2){ 
    p2(p1); 
})(true, function(p1){ // an anonymous function passed as an argument. 
    m = 3; 
    if(p1){...} 
}); // the end of self-invoked function expression. 
+0

可能是'{p1:true,m:3}'? –

+0

該函數可以訪問定義的作用域幷包含任何父作用域(例如全局/窗口)。如果在另一個函數內部定義,它可以訪問該函數中定義的任何變量。如果像回調那樣作爲參數傳入,它將無法訪問在它傳入的函數中定義的變量,因爲它在該函數之外定義並作爲參數傳入。 –

+0

伊斯蘭巴巴耶夫抱歉沒有得到它。 Jonathan Kuhn所以問題是,我應該將參數列表中定義的匿名函數看作是另一個函數內定義的函數嗎? –

回答

1

的功能都可以訪問它被限定的範圍,並且包括任何父範圍(例如全球/窗口)。如果在另一個函數內部定義,它可以訪問該函數中定義的任何變量。如果像回調那樣作爲參數傳入,它將無法訪問在它傳入的函數中定義的變量,因爲它在該函數之外定義並作爲參數傳入。

例子:

var a = 1; 

(function(callback){ //func1 
    //access variable in parent scope 
    console.log('func1', a); //outputs 1 

    //define a new variable within this function's scope 
    var b = 2; 

    //call our callback 
    callback(); 

    //define and call a function within this function's scope 
    (function(){ //func3 
     //access variable in parent scope 
     console.log('func3', a); //outputs 1 
     //access variable in parent function scope 
     console.log('func3', b); //outputs 2 
    })(); 

})(function(){ //func2 
    //access variable in parent scope 
    console.log('func2', a); //outputs 1 
    //access variable from invoking function 
    console.log('func2', b); //outputs undefined 
}); 

這將輸出類似:

func1 1 
func2 1 
func2 undefined 
func3 1 
func3 2 

,所有的功能都可以看到變量a,因爲它是在一個父範圍擴大到所有的功能。參數函數看不到變量b,因爲b是在另一個函數中定義的,而參數函數是在外部定義的並作爲參數傳入的。第一個函數中定義的函數可以同時看到ab

0

調用一個IIFE與首先將該函數分配給一個變量,然後通過該變量調用該函數實際上是一樣的;與任何其他使用匿名函數一樣,它只是一個避免給函數命名的快捷方式。所以:

(function(p1,p2){ 
    p2(p1); 
})(true, function(p1){ // an anonymous function passed as an argument. 
    m = 3; 
    if(p1){...} 
}); 

相當於:

var temp = function(p1,p2){ 
    p2(p1); 
}; 
temp(true, function(p1) { 
    m = 3; 
    if(p1){...} 
}); 

除了加入的temp到外範圍;因爲這個變量沒有出現在其他地方,所以它沒有效果。所有其他變量的範圍在兩種情況下是相同的。

1

如果您不確定在調用的參數列表中定義一個函數的範圍時,請注意

fn(function x(…) { … }) 

相當於

_temp = function x(…) { … }; 
fn(_temp) 

參數之前的實際評估呼叫,並且他們的評估範圍與呼叫本身的評估範圍相同。

相關問題