2013-07-01 1 views
0

У меня есть следующий JavaScript код:JavaScript область видимости в пределах цикла

for (var x = 0; x < queue.length; x++) { 
    var song = new Song().loadJSON(queue[x]); 
    //Not already loaded 
    if (loaded.indexOf(song.url) == -1) { 
     addRow("play", song.url, song.title, song.album, song.artist); 
     loaded.push(song.url); 
     songs.push(song); 
     if (song.duration == 0) { 
      var audio = $("<audio>"); 
      audio.attr("songid", songs.length - 1); 
      console.log("Writing:", audio.attr("songid")); 
      audio.on("durationchange", function() { 
       var id = audio.attr("songid"); 
       console.log("Reading:", id); 
       songs[id].duration = audio[0].duration; 
      }); 
      audio.attr("src", song.url); 
     } 
    } 
} 

Это печатает:

Writing: 0 
Writing: 1 
Writing: 2 
(3x) Reading: 2 

Что приводит меня к мысли, что songid атрибут записывается поверх каждой итерации для цикла. Я не уверен, как это возможно, потому что звуковая переменная является локальной для каждой итерации. Что я делаю не так?

+0

Что заставляет вас верить, что 'audio' переменная«локальный»? – zeroflagL

+3

JavaScript имеет * только * область действия (или глобальную область). Блоки не создают область. Кроме того, добро пожаловать на закрытие JavaScript! –

+0

@zeroflagL был создан в этом цикле. У меня нет ссылки на него где-то вне цикла. Разве это не делает его локальным? –

ответ

0

var audio = $("<audio>"); является глобальной переменной или в глобальном масштабе, если только для цикла внутри функции.

if и for не создает новую область видимости, поэтому variable audio написали поверх.

Итак, ваши веры верны.

Только переменные в функции находятся в новой области или параметрах, переданных функции.

http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html

Ex:

var someVariable; //global scope. 
function abc() { 
    var someVariable; //in new scope. 
} 
or 
var fn = function() { var inNewScope;}; 

Другой способ создать новую область видимости

callingFunction(parameter); 

переменная параметр бы в новой области внутренней этой функции.

Другая полезная ссылка: http://bonsaiden.github.io/JavaScript-Garden/

Подъемно:. Когда объявления переменных, а не присваивание, & функция декларации перемещается вверх большая часть объема они были определены в

Закрытие: Когда переменные из внешнего scoper поддерживаются в живых, даже если сама область не существует. Обычно, когда внутренняя переменная доступа к области видимости находится в области внешнего охвата. Пример: если есть функция, которая возвращает другую функцию, и эта возвращаемая функция использует переменную, которая была определена его родительской функцией, а не в ней, то ссылка на эту функцию сохраняет эту переменную, даже если эта родительская функция вернулась и больше не существует.

Чтобы узнать больше, попробуйте следующее: http://javascriptweblog.wordpress.com/2010/07/06/function-declarations-vs-function-expressions/

Смежные вопросы