Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/438.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 从事件处理程序回调调用的函数中的'this'值?_Javascript - Fatal编程技术网

Javascript 从事件处理程序回调调用的函数中的'this'值?

Javascript 从事件处理程序回调调用的函数中的'this'值?,javascript,Javascript,我已经对相关代码进行了注释。通过反复试验,我发现我必须在事件处理程序和命名回调中使用bind,才能使事情正常工作 我并不觉得这是直观的,因为我认为命名回调将使用this值调用函数,该值指向包含的对象文本 我知道事件处理程序需要绑定b.c。通常回调会指向触发事件的元素 但是第二个绑定是必需的,我不理解其机制/概念 有一个//*表示焦点区域 NS.parsel({ Name: 'MSimMenu', E: { hold_name: '#hold_nam

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

我并不觉得这是直观的,因为我认为命名回调将使用this值调用函数,该值指向包含的对象文本

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

但是第二个绑定是必需的,我不理解其机制/概念

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

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';
    }
});
这是因为这取决于函数的调用方式。对于setTimeout回调,它不是在NS对象的上下文中调用的,而是作为一个独立函数调用的。在这种情况下,这是未定义的,返回到全局对象

关于绑定事件处理程序,您可能对另一种方法感兴趣,该方法使您的对象实现EventHandler接口。stackoverflower的一位同事最近建议,请参阅的公认答案。

这是因为这取决于函数的调用方式。对于setTimeout回调,它不是在NS对象的上下文中调用的,而是作为一个独立函数调用的。在这种情况下,这是未定义的,返回到全局对象


关于绑定事件处理程序,您可能对另一种方法感兴趣,该方法使您的对象实现EventHandler接口。stackoverflower的一位同事最近建议,在JavaScript中,当一个函数调用另一个函数时,“this”关键字会更改上下文。上下文是函数的直接调用方。

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

@pure_code.mom我不确定他所说的直接调用方是什么意思。但是如果你叫NS.hidebotom,那么这就是NS;但是如果你做var func=NS.hidebotom;func,则它将是全局对象。或者,如果执行var o={fn:NS.hideBottom};o、 fn,那么这将是o.@pure_代码。妈妈哈哈哈,谢谢!还有一件事可能会为您澄清这个问题:奇怪的效果是因为函数/方法不属于任何特定对象,它们只是作为引用附加;事实上,同一个函数对象可以有多个父对象,正如我上面评论中的示例所示。因此JS无法知道将函数绑定到哪个对象,您必须手动绑定。@pure_code.mom我不确定他所说的直接调用方是什么意思。但是如果你叫NS.hidebotom,那么这就是NS;但是如果你做var func=NS.hidebotom;func,则它将是全局对象。或者,如果执行var o={fn:NS.hideBottom};o、 fn,那么这将是o.@pure_代码。妈妈哈哈哈,谢谢!还有一件事可能会为您澄清这个问题:奇怪的效果是因为函数/方法不属于任何特定对象,它们只是作为引用附加;事实上,同一个函数对象可以有多个父对象,正如我上面评论中的示例所示。因此JS无法知道将函数绑定到哪个对象,您必须手动绑定它。