Нужно уточнить проблему петли в замыканиях - PullRequest
1 голос
/ 01 марта 2011

, поэтому я понимаю замыкания и циклические ссылки (надеюсь), но одним из аспектов является сообщение о замыкании в цикле, которое, как представляется, вызывает много затруднений. Мне нужно уточнить это. Код, на который я смотрю:

function showHelp(help) {
  document.getElementById('help').innerHTML = help;
}

function getHelp(help) {
  alert(help); 
  // only to show value of "help" at this point, also to prove that "getHelp()" is being called even
  // though the onfocus wasn't used

  return function() {
    showHelp(help);
  }
}

function setupHelp(){
  var helpText = [
    {'id':"email",'help':"Your email address"},
    {'id':"name",'help':"Your full name"},
    {'id':"age",'help':"Your real age"}
  ];

  for(var i=0;i<helpText.length;i++){
    var item = helpText[i];
    alert(item.help);
    // only to show value of "help" at this point, also to prove that "getHelp()" is
    // being called even though the onfocus wasn't used
    document.getElementById(item.id).onfocus = getHelp(item.help);
  }
}

Предполагается, что у вас есть три поля ввода и их фокусировка вернет полезную подсказку (как видно из статьи MDC). Но вот в чем суть моей нехватки понимания: если вы помещаете предупреждение (для проверки) в функцию «getHelp ()» и помещаете его в функцию «setupHelp ()» непосредственно перед тем, как установить привязку события обработчик ссылки на элемент dom, вы увидите, что при загрузке страницы выполняется цикл, затем функция getHelp (), затем цикл, затем функция getHelp () и т. д. до конца цикла , Так что, если функция getHelp () связана с обработчиком события onfocus, и вы даже не фокусируете поля ввода, как функция getHelp () может работать ?? И как JAvaScript хранит все возможные результаты этого маленького цикла? : S

Любая помощь, которую вы могли бы оказать, действительно помогла бы, это ошеломляет прямо сейчас. Я уверен, что это просто щелкнет один из этих дней, но я нетерпеливый. : P

Том.

Ответы [ 2 ]

1 голос
/ 01 марта 2011

Так что, если функция getHelp () связана с обработчиком события onfocus, и вы даже не фокусируете поля ввода, как может работать функция getHelp () ?? И как JAvaScript хранит все возможные результаты этого маленького цикла?

Это суть вашего вопроса, и ответ лежит здесь:

for(var i=0;i<helpText.length;i++){
    var item = helpText[i];
    alert(item.help);
    // only to show value of "help" at this point, also to prove that "getHelp()" is
    // being called even though the onfocus wasn't used
    document.getElementById(item.id).onfocus = getHelp(item.help);
}

Это , как интерпретатор JavaScript хранит все возможные результаты: потому что вы сказали ему, что они были. Вы вызываете getHelp, который генерирует функцию, а затем возвращает эту функцию.

Как это работает, намного проще, чем кажется. :-) Я вхожу в это справедливо здесь , но в основном: Когда вы вызываете функцию, создается нечто, называемое контекст выполнения . Это объект (JavaScript массово объектно-ориентированный, вплоть до уровня интерпретатора). В этом объекте контекста выполнения есть нечто, называемое переменный объект . Он содержит все переменные для контекста выполнения в качестве свойств. Это включает в себя аргументы функции, все var s внутри функции, а также все объявленные функции (у вас нет объявленных функций в вашем примере, поэтому мы можем игнорировать это; вы есть только функциональные выражения, что нормально). Любая функция, объявленная или определенная выражением в контексте выполнения, имеет постоянную ссылку на объект переменной для этого контекста выполнения и использует ее для разрешения ссылок на переменные при вызове.

Итак: в вашем цикле, когда вы вызываете getHelp, создается объект, хранящий данные, связанные с этим вызовом. Этот объект привязан к функции, которую вы создаете в вызове и сохраняете в обработчике onfocus (это данные, которые функция закрывает по [именно поэтому она называется closure )]. Когда / если вызывается обработчик, таким образом разрешаются ссылки, которые содержит функция, на свойства этого объекта.

Подробнее: Затворы не сложны

0 голосов
/ 01 марта 2011

на самом деле, вы присваиваете результат из getHelp(help) для вашего события onfocus, поэтому абсолютно нормально, что оба оповещения отображаются, так как getHelp выполняется, чтобы дать свой результат.Если вы поместите предупреждение в функцию возврата, я почти уверен, что вы его не увидите:

function getHelp(help){
    return function(){
        alert(help); 
        showHelp(help);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...