1

我已经评论了相关代码。我通过反复试验发现,我必须在事件处理程序和命名回调中都使用 bind 才能使事情正常工作。

我没有发现这很直观,因为我认为命名回调会调用函数,其值 this 指向包含对象字面量。

我知道事件处理程序需要绑定 bc 通常回调将指向触发事件的元素。

但是第二个绑定(我验证是必需的),我不了解机制/概念。

有一个// *表示焦点区域。

NS.parsel({
    Name: 'MSimMenu',
    E: {
        hold_name:         '#hold_name',
        wrap_bottom:       '#wrap_bottom'
    },
    A: {
        time_out_id:        null,
        TIME_DELAY:         1000
    },
    init: function () {
        var self = this;
        self.E.hold_name.addEventListener(   "mouseover",   self.mouseOverTop.bind(self),    false);
        self.E.wrap_bottom.addEventListener( "mouseover",   self.mouseOverBottom.bind(self), false);
        self.E.wrap_bottom.addEventListener( "mouseout",    self.mouseOut.bind(self),        false);
        self.E.hold_name.addEventListener(   "mouseout",    self.mouseOut.bind(self),        false);
    },

    // callbacks

    mouseOverTop: function () {
        NS.clearTimeout(this.A.time_out_id);
        this.showBottom();
    },
    mouseOverBottom: function () {
        NS.clearTimeout(this.A.time_out_id);
    },        
    mouseOut: function () {

        // * this regards the question
        // bind is required here for hideBottom to have correct value of this

        this.A.time_out_id = NS.setTimeout(this.hideBottom.bind(this), this.A.TIME_DELAY);
    },

    // called from callbacks

    showBottom: function () {
        this.E.wrap_bottom.style.visibility = 'visible';
    },
    hideBottom: function () {
        this.E.wrap_bottom.style.visibility = 'hidden';
    }
});
4

2 回答 2

5

那是因为this是根据函数的调用方式确定的。在setTimeout回调的情况下,它不是在您的 NS 对象的上下文中调用,而是作为一个独立的函数调用。在这种情况下this是未定义的,回退到全局对象。

关于绑定的事件处理程序,您可能对另一种方法感兴趣,它使您的对象实现EventHandler接口。stackoverflower 的一位同事最近一直在建议,请参阅如何在 JavaScript 中实现 DOM 数据绑定的已接受答案。

于 2013-06-11T16:15:16.820 回答
1

在 JavaScript 中,当一个函数调用另一个函数时,“this”关键字会改变上下文。上下文是函数的直接调用者。

于 2013-06-11T16:17:01.590 回答