2011-04-02 2 views
1

Пример 1: http://jsfiddle.net/ufCr8/Закрытие путаница Javascript

function createFunctions() { 
    var result = new Array(); 

    for (var i = 0; i < 10; i++) { 
     result[i] = function() { 
      return i; 
     }(); 
    } 

    return result; 
} 

var funcs = createFunctions();  
for (var i = 0; i < funcs.length; i++) { 
    document.write(funcs[i] + "<br />"); 
} 

Пример 2: http://jsfiddle.net/T5shB/

function createFunctions() { 
    var result = new Array(); 

    for (var i = 0; i < 10; i++) { 
     result[i] = function(num) { 
      return function() { 
       return num; 
      }; 
     }(i); 
    } 

    return result; 
} 

var funcs = createFunctions(); 
for (var i = 0; i < funcs.length; i++) { 
    document.write(funcs[i]() + "<br />"); 
} 

Почему те два получить разные результаты?

+2

У них такой же результат для меня. – icktoofay

+0

Да, такой же результат для меня тоже. Вы используете странный браузер? –

+0

Я тоже получаю тот же результат. Обратите внимание, что все функции выполняются внутри цикла for, поэтому значения, присвоенные 'result [i]', «заморожены». Если бы вы вместо этого удалили '()' и запустили 'result [i]()' вне цикла for, вы увидите список распечатанных «9». – monsur

ответ

3

Эти обе работают правильно. (И имеют те же результаты).

Образец # 1:

for (var i = 0; i < 10; i++) { 
    result[i] = function() { 
     return i; 
    }(); // note function application! 
} 

Анонимный функция выполняется прямо тогда и результат представляет собой число (ток ) значение i каждой итерации цикла. Это фактически то же самое, что и result[i] = i. Не очень интересно. (В цикле, который печатает значение вне, не существует приложения-функции, которое было бы ошибкой как число, если не функция - в этом случае оно отличается от образцов ниже.)

Образец № 2:

for (var i = 0; i < 10; i++) { 
    result[i] = function(num) { 
     return function() { 
      return num; 
     }; 
    }(i); 
} 

внешняя анонимная функция, которая применяется возвращает замыкание, которое правильно «двойные св зываетс» к текущему значению i, который передается в качестве num (num на самом деле связаны свободной переменной). Помните, что функции вводят новую область - var (или for) нет.

Я подозреваю, что «в противном случае» будет:

for (var i = 0; i < 10; i++) { 
    result[i] = function() { 
     return i; 
    }; // note function NOT invoked here! 
} 

... 
for (var i = 0; i < funcs.length; i++) { 
    document.write(funcs[i]() + "<br />"); 
} 

Это даст «странные результаты», потому что это тот же самый i, который связан в каждом замыкании (т.е. i является и есть только один i). Таким образом, когда функция будет выполнена, она вернет текущее значение i в точке выполнения.

Счастливого кодирование


Я рекомендую прочитать Jibbering JavaScript Closure Notes - это не самый начинающий ресурс, но я считаю его доступным, и это объясняет вещи достаточно подробно. (И далеко, гораздо читабельнее, чем спецификация ECMAScript, IMOHO).

+1

Прекрасный пример того, почему полезно использовать явные круглые скобки вокруг вызываемых функций, даже если они не нужны, как в этой ситуации. – Reid

+0

Спасибо человек. Ваш ответ очень полезен. Хорошего дня. – jsnewman

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