2012-07-20 173 views
5

給定以下代碼,我應該期望在警報中看到什麼?作爲函數參數傳遞的匿名函數的作用域

var a = 100; 
function afunc(infunc){ 
    a = 10; 
    infunc.call(); 
} 

afunc(function(){alert(a)}); 

我最初的想法是,我的瀏覽器應提醒100自變量a = 100將是作用域作爲參數傳遞afunc匿名函數。但是,這假定匿名函數實際上是在全局上下文中定義的。顯然,當瀏覽器警告10時情況並非如此。那麼,爲什麼a = 10在範圍鏈中的a = 100之前呢?

謝謝!

回答

6

因爲您在調用匿名函數之前將a設置爲10。 a實際上是全局的,但你將它設置爲10.

+3

Facepalm!現在我感到很傻。 – 2012-07-20 16:31:34

+0

是的,這是正確的原因 – 2012-07-20 16:36:01

6

那麼,爲什麼a = 10在範圍鏈中的a = 100之前呢?

不是。您只定義了1 a變量,在變爲警報之前,該變量僅從100更改爲10

如果你想a使他能與自己的價值觀不同的變量,它們都需要一個var關鍵字:

var a = 100 
function afunc(infunc){ 
    var a = 10; 
    infunc.call(); 
} 

afunc(function(){alert(a)})​ 
1

請看下面的例子:

var a = 100; 

function afunc(infunc){ 
    a = 10; 
    var f = function(){ 
    console.log(a); 
    }; 
    f.call(); 
    infunc.call(); 
} 

afunc(function(){ console.log(a); }); 

我們指定的值10到aafunc的範圍內,然後依次調用兩個函數,即只記錄a的值。在這種情況下,您會希望這兩個函數都記錄爲a的值,實際上會發生什麼情況。

在您的示例中,infunc將在與afunc中定義的任何本地函數基本相同的範圍內執行,而不管它實際定義在何處。由於您在較窄的範圍內爲a分配了值,因此在撥打infunc時,值爲a

功能保留從他們的定義一些範圍,如下面的例子:

function bfunc(){ 
    var b = 'hello'; 
    return function(){ console.log(b); }; 
} 

afunc(bfunc()); 

這裏,bfunc返回的匿名函數實際上是從afunc範圍內調用,但它仍然能夠記錄在原始範圍內分配的正確值b。如果要更改afunc以將不同的值分配給b,它仍會記錄"hello",因爲afunc中定義的b是與bfunc中定義的b中定義的變量不同的變量。