Вариация классической печально известной дилеммы - PullRequest
0 голосов
/ 19 июля 2011

Почти каждый сталкивался с этой конкретной проблемой:

function addLinks () {
    for (var i=0, link; i<5; i++) {
        link = document.createElement("a");
        link.innerHTML = "Link " + i;
        link.onclick = function () {
            alert(i);
        };
        document.body.appendChild(link);
    }
}
window.onload = addLinks;

Значение i после того, как цикл кэшируется.Замыкание может использоваться для создания «живой» ссылки:

function addLinks () {
    for (var i=0, link; i<5; i++) {
        link = document.createElement("a");
        link.innerHTML = "Link " + i;
        link.onclick = function (num) {
            return function () {
                alert(num);
            };
        }(i);
        document.body.appendChild(link);
    }
}
window.onload = addLinks;

Мы также можем использовать самозапускающийся anon fns для создания замыканий и т. Д.

Моя ситуация

Проблема, с которой я сталкиваюсь, та же, но контекст немного другой.Вот неудачный пример :

Нажмите «добавить еще несколько раз» и нажмите «ударить меня», что выдаст предупреждение -1.Значение maxIndex кэшируется.Соответствующий код:

  var attached = false;

function actions() {
    var elements = $('body').find('li');
    var maxIndex = elements.length -1;


        var cycle = {
            next: function() {
                alert( maxIndex );
            }
        };

        if ( !attached ) {
            $('#next').click(function(e) {
                cycle.next();
            });
            attached = true;
        }

};

actions();

$('#add').click(function(e) {
    e.preventDefault();
    $('<li/>').text('god').appendTo('body');
    actions();
});

Я пытался применить замыкания безрезультатно.(см. http://jsfiddle.net/Bfcus/23/ и вплоть до / 1 /).

Я не хочу использовать with операторы или let операторы / выражения для решения этой проблемы.Я знаю, что это можно решить еще одним способом - изменить maxIndex на свойство именованного объекта.Вот рабочий пример , делающий это таким образом.

Мне интересно то, есть ли способ заставить его работать, сохраняя определение переменной elements внутри actionфункция, а переменная maxIndex определена в той же области видимости?По сути, можно ли настроить http://fiddle.jshell.net/r7Ekj/2/show/ так, чтобы он работал почти так же, как и без использования свойства / let / object?

1 Ответ

1 голос
/ 19 июля 2011

Странно, иногда создание подробного вопроса на самом деле помогает вам решить его, и я клянусь, я не решил его заранее ...

Я только что создал переменную maxIndex вне области действия actionsи фактически назначить его внутри .. это заставляет его работать, потому что оно не определено в одной и той же области видимости функции, и поэтому привязка ведет себя по-разному.

http://fiddle.jshell.net/r7Ekj/9/

(Как неловко?)

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