Закрытие путаницы в Javascript - PullRequest
1 голос
/ 02 апреля 2011

Образец 1: http://jsfiddle.net/ufCr8/

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 />");
}

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

1 Ответ

3 голосов
/ 02 апреля 2011

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

Образец № 1:

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

Анонимная функция выполняется прямо тогда , и результатом является числовое ( current ) значение 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 Заметки о закрытии - это не самый начинающий ресурс, но я нахожу его доступным и объясняет все достаточно подробно. (И намного, намного более читабельно, чем спецификация ECMAScript, IMOHO).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...