2013-06-28 7 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 без необходимости проходить эту величину в.

Редактировать
Хорошо, я вроде поторопился на этом , Я, хотя у меня была проблема с большой переменной, но, по-видимому, моя проблема заключалась в том, что в моем конкретном коде я использовал имя переменной arguments вместо notGlobalVariable, и, как я должен был знать, arguments затенен и ссылается на аргументы, переданные в Я сменил имя на args, и он отлично работает. Сожалею!

+3

В чем проблема? Ваш пример отлично работает. –

+3

Ваш пример должен работать. Возможно, вы назначаете 'myOtherFunction' и не вызываете' myOtherFunction' с 'myOtherFunction()' –

+0

http://jsfiddle.net/N4kfY/1/ - работает для меня. –

ответ

4

JavaScript делает это автоматически, создавая замыкания.

  • Каждая функция создает свой собственный объем.
  • Области вложенные, поскольку функции могут быть определены внутри функций.
  • Каждая новая вложенная область («function») может видеть все переменные, которые были определены в любой родительской области в точке создания (то есть новой функции). Это называется замыканием.
  • Каждая переменная из любой родительской области «по ссылке» - дочерние области («функции») всегда видят их текущие значения.
  • Точка во времени, когда функция работает не имеет значения, только момент времени, когда было объявлено (см. Первый пример).
  • Объем, в котором функция работает в, не имеет значения, только область функции определена в (см. Второй пример).

Здесь

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 могут видеть myGlobalVariable и notGlobalVariable.

Теперь предположим, небольшое изменение:

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]); 

Проблема ОР заложен на самом деле в коде он не в курсе, но этот пример кода отвечает оригинал вопрос - закрытие все еще работает в javascript, как и ожидалось.

+0

Любые объяснения для downvote? Он работает - скрипка прилагается. – ElmoVanKielmo

+1

Я не знаю человека, но он выглядит точно так же, как у OP (кроме добавленного вызова функции) –

+0

И этот пропущенный вызов был именно тем, что вызвало 'notGlobalVariable', чтобы не быть нажатым в' myGlobalVariable' ... – ElmoVanKielmo

1

У вас есть доступ к notGlobalVariable внутри myOtherFunction. Однако вы назначаете только myOtherFunction и никогда не вызываете его. Обратите внимание, что вам нужно будет вызвать myOtherFunction внутри myFunction.

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 вы получили downvotes либо потому, что вы не объяснили свой ответ, либо потому, что люди ответили на ваши комментарии. Они пришли как немного подлый ИМО ... даже если вы их не собирались. –