2013-06-28 61 views
3

我真的看了這麼多,並沒有找到一個真正解釋這個問題的答案...是否可以在函數中使用非全局變量?

我知道如何從函數內部訪問全局變量。

myGlobalVariable = []; 
function myFunction() { 
    myGlobalVariable.push("somedata"); 
} 

現在如何訪問範圍鏈上的一個變量,如果它不是全局的?

myGlobalVariable = []; 

function myFunction() { 

    var notGlobalVariable = "somedata"; 

    var myOtherFunction = function() { 
    myGlobalVariable.push(notGlobalVariable); // This is what I'd like to be able to do. 
    } 

} 

我知道我可以做這樣的事情

var notGlobalVariable = "somedata"; 

var myOtherFunction = function(arg) { 
    myGlobalVariable.push(arg); 
} 

myOtherFunction(notGlobalVariable); 

但調用該方法只有當我有notGlobalVariable一應俱全工程價值的功能。我希望做能夠在全球範圍內調用函數,並將它總是使用最初由notGlobalVariable保存的值,而不必通過該值。

編輯
好吧,我還挺跳上這一槍。不過,我覺得我有一個很大的變量範圍的問題,但顯然我的問題是,在我的特定代碼,我代替notGlobalVariable使用變量名arguments,並作爲我應該知道,arguments被遮擋時,是指在傳遞的參數。我將名稱更改爲args,它工作正常。抱歉!

+3

這是什麼問題?你的例子完美地工作。 –

+3

你的例子應該工作。也許你只是分配'myOtherFunction'而不是'myOtherFunction()'調用'myOtherFunction'' –

+0

http://jsfiddle.net/N4kfY/1/ - 適用於我。 –

回答

4

JavaScript通過創建閉包自動執行。

  • 每個函數都創建自己的作用域。
  • 範圍是嵌套的,因爲函數可以在函數中定義。
  • 每個新的嵌套範圍(「函數」)都可以看到在任何父範圍中(即新函數的)創建點處定義的所有變量。這被稱爲封閉。
  • 任何父範圍的每個變量是「參照」 - 子作用域(「功能」)總能看到它們的當前值。
  • 的時間點,當函數運行無所謂,只有在當它被宣佈的時間點(見示例)。
  • 功能中運行的範圍無關緊要,只有(參見第二個示例)中定義的功能範圍爲

這裏

var myGlobalVariable = []; 

// define function => creates closure #1 
function myFunction() { 
    var notGlobalVariable = "somedata"; 

    // define function => creates closure #2 
    var myOtherFunction = function() { 
    myGlobalVariable.push(notGlobalVariable); 
    } 

    // execute function 
    myOtherFunction(); 
} 

myFunction(); // myGlobalVariable will be ["somedata"] 

創建兩個作用域:

  1. myFunction可以看到myGlobalVariable
  2. 存儲在myOtherFunction可以看到myGlobalVariablenotGlobalVariable匿名函數。

現在假設一個小的變化:

var myGlobalVariable = []; 

// define function => creates closure #1 
function myFunction(callback) { 
    var notGlobalVariable = "somedata"; 

    // define function => creates closure #2 
    var myOtherFunction = function() { 
    myGlobalVariable.push(callback()); 
    } 

    // execute function 
    myOtherFunction(); 
} 

// define function => creates closure #3 
function foo() { 
    var thisIsPrivate = "really"; 

    // define function => creates closure #4 
    return function() { 
    return thisIsPrivate; 
    } 
} 

myFunction(foo()); // myGlobalVariable will be ["really"] 

你看到callback功能訪問thisIsPrivate,因爲它是在正確的範圍定義,即使範圍內,可以執行看不到變量。

同樣,callback函數將無法看到notGlobalVariable,即使該變量在執行回調的作用域中可見。

請注意,您總是必須在您定義的任何變量上使用var。否則,變量將會默默地全局化,這會導致難以修復程序中的錯誤。

+0

+1有關範圍和封閉的詳細說明。如果可以的話,我會給+100。現在我很尷尬與我簡潔的回答:( – ElmoVanKielmo

1

是的,你可以 - 在JavaScript中一切皆有可能 - 這裏是小提琴http://jsfiddle.net/AZ2Rv/

myGlobalVariable = []; 

function myFunction() { 

    var notGlobalVariable = "somedata"; 

    // The following assigns a function to a variable 
    var myOtherFunction = function() { 
    myGlobalVariable.push(notGlobalVariable); 
    } 

    // The following line was missing in the code in the question so the function 
    // was never called and `notGlobalVariable` wasn't pushed into `myGlobalVariable` 
    myOtherFunction(); 
} 

// And just to test if it works as expected 
myFunction(); 
alert(myGlobalVariable[0]); 

的代碼實際上奠定了OP他沒有公佈的問題,但此示例代碼回答原如預期的那樣,問題 - 關閉仍然可以在JavaScript中工作。

+0

downvote的任何解釋?它的工作 - 小提琴附加。 – ElmoVanKielmo

+1

我不認識人,但它看起來和OP已經有的一樣(除了添加的函數調用) –

+0

而這個缺失的調用正是導致'notGlobalVariable'不能被推入'myGlobalVariable'的原因...... – ElmoVanKielmo

1

您有權訪問myOtherFunction中的notGlobalVariable。但是,您只分配myOtherFunction並且從不調用它。請注意,您必須在myFunction之內調用myOtherFunction

function myFunction() { 

    var notGlobalVariable = "somedata"; 

    var myOtherFunction = function() { 
    myGlobalVariable.push(notGlobalVariable); // This is what I'd like to be able to do. 
    } 
    //Invoke myOtherFunction() 
    myOtherFunction() 

} 
+0

@ElmoVanKielmo您收到了贊成票或者是因爲您沒有解釋您的答案,或者是因爲人們回覆了您的意見。他們來來往往是一個有點卑鄙的國際海事組織......即使你不打算這樣做。 –

相關問題