2012-06-17 1 views
1

Каков правильный способ установки соответствующих значений?
Как сделать эту работу «для ... в».Область применения при динамическом связывании общих функций с объектами. (шаблон модуля)

Функция, которую я связываю с self [state], появляется после цикла с последним значением состояний [state], а не ассоциированным с ним во время цикла.

cssbtn = function(id, states, state){ 

    var self = document.getElementById(id); 
    var states = states || {'off': '0px 0px', 'selected': '-20px 0px', 'selected2': '-40px 0px' }; 
    var state = state || 'off'; 

    for (state in states) { 
    self[state] = function(){ 
     alert(states[state]); //demo purposes 
    } 
    } 

    self.onmouseover = function(evt){ 
    self.selected(); 
    } 

    self.onmouseout= function(evt){ 
    self.off(); 
    } 

    self.onclick= function(evt){ 
    self.selected2(); 
    } 

    return self; 
} 
+0

Ах, когда-либо столь распространенные затворы внутри для петлей снова набрасываются. – hugomg

+0

Возможно, это не ошибка, поскольку она соответствует спецификациям? Это определенно ловушка. – user1446253

+0

Ну, для вас это было, но, по крайней мере! – hugomg

ответ

1

один правильный ответ:

self[state] = (function(i) { return function() { alert(i) } })(states[state]); 

наткнулся на него из: How can one de-reference JavaScript variables when enclosing an outer scope

Является ли это единственный способ? Более очевидный/элегантный многоязычный (не такой javascript) подход?

+1

В будущих версиях javascript (и некоторых браузерах, если вы разрешаете расширения) вы можете объявлять переменные с «let» вместо «var», чтобы использовать лексическую область, которая не подвержена ошибкам закрытия для цикла. В противном случае вам нужно явно сохранить состояние где-то: это можно сделать либо с помощью объектов, либо с помощью таких функций, как вы (хотя я предпочитаю создавать именованную функцию типа make_alerter вместо использования функции anon) – hugomg

+0

И, конечно, другая возможность использует функцию «forEach» из некоторой библиотеки (аналогично методу Array foreach, найденному в современных средах JS). Вы теряете доступ к ранним «разрывам» и «возврату», но поскольку итерация завернута в обратный вызов, индексная переменная правильно закрыта и не используется повторно. – hugomg

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