2009-12-08 2 views
0

У меня есть объект, определенный как это:Вызов функции в объектах с Javascript

Blah = { 

    hideTimer:null, 

    setTimer: function() { 
    this.hideTimer = window.setTimeout(Blah.hidePopupInner, 500); 
    // must be done via window due to Greasemonkey 
    }, 

    hidePopupInner: function() { 
    log("This? " + this); 
    }, 

    hidePopupInnerPublic: function() { 
    Blah.hidePopupInner(); 
    } 
} 

Проблема заключается в том, что «это» в KillTimer является не набора для скучных. Если бы я изменить строку сказать

this.hideTimer = window.setTimeout(Blah.hidePopupInnerPublic, 500); 

то «это» указывает на скучное так hideTimer могут быть использованы.

Создание «общедоступного» метода для каждого метода решает проблему, но должно быть более простое решение ...?

Примечание: Это все в Greasemonkey, но я думаю, что это общий вопрос Javascript.

ответ

6

Чтобы решить эту проблему, вы можете использовать анонимную функцию и справку по объему при построении таймаута.

(code...) 
setTimer: function() { 
    var _this = this; 
    this.hideTimer = window.setTimeout(function(ms){ 
     _this.hidePopupInner(); 
    }, 500); 
}, 
(code...) 

PS: Кроме того, setTimeout будет передавать количество миллисекунд на вызываемую функцию. Например: представьте, что ваша функция может принимать один параметр и делать с ней кое-что. Но поскольку setTimeout будет передавать миллисекунды вашей функции, это может привести к непредвиденным ошибкам.

+0

Не могли бы вы разъяснить свой PS? Вы имеете в виду в моем коде в вопросе, он это сделает? –

+0

Мой PS, это только мой собственный опыт с setTimeout, он не будет создавать никаких проблем в вашем случае. – nemisj

+0

Отлично, спасибо за это –

2

В основном функция, указанная как параметр setTimeout, выполняется как обратный вызов.
Причина, по которой вы не получаете контекст Бла, - это переход в область setTimeout (даже при использовании метода Бла).

Я не знаю Greasemonkey вообще, но используя методы функции, такие как Bind поможет вам. Если в GM нет функции, подобной bind, вы можете написать ее, но вы сами (пара строк кода) - можете копировать PrototypeJS.
http://www.prototypejs.org/api/function/bind

Это в основном выполняет подготавливает функцию с предписанной в технических заданиях сферы:

// inside Blah 
setTimeout (Blah.hidePopupInner.bind(this), 500); 

На самом деле решением Tableton является реализацией BIND на лета

+0

классно, я проверю это, или даже могу поставить Prototype с моим скриптом. Благодаря! –

1

Хотя не истинное решение проблемы области видимости, вы можете хотя бы обойти Blah.killTimerPublic:

window.setTimeout(function(){ Blah.hidePopupInner() }, 500); 
+0

Спасибо, Джастин. Хотя это работает, оно работает только для одного экземпляра ... так оно и есть в этом случае, так что +1 –