开发者

Calling Functions in Objects with Javascript

I have an object defined like this:

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();
   }
}

The problem is that the 'this' in killTimer is not set to Blah. If I change the line to say

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

then the 'this' is pointing to Blah so the hi开发者_如何学JAVAdeTimer can be utilized.

Making a 'public' method for each method solves the problem, but there must be an easier solution...?

Note: This is all in Greasemonkey, but I think it's a general Javascript question.


To solve this, you can use anonymous function and scope reference when building timeout.

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

PS: Moreover, setTimeout will pass the number of milliseconds to invoked function. For example: imagine your function can receive one parameter, and do some stuff with it. But because setTimeout will pass milliseconds to your function, it can lead to unexpected errors.


Basically function specified as setTimeout param is executed like callback.
Reason you're not getting Blah context is you switching to setTimeout scope (even when using Blah method).

I don't know Greasemonkey at all, however using Function methods like Bind will help you. If there is no function like bind in GM, you can alwyas write it but yourself (couple of lines of code) - can copy PrototypeJS one.
http://www.prototypejs.org/api/function/bind

It basically executes prepares your function with specifed scope:

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

Actually Tableton's solution is Bind's implementation on fly


Though not a true solution to the scope issue, you can at least get around Blah.killTimerPublic by doing:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜