Javascript js:keypress事件中对象的范围

Javascript js:keypress事件中对象的范围,javascript,Javascript,以下是我的JS简单脚本: var Chat = function() { console.log("init"); this.debug = function (txt) { console.log(txt); } document.getElementById('shoutBoxInput').addEventListener("keypress", keyPressedFunction, false); this.keyPressedF

以下是我的JS简单脚本:

var Chat = function() {
    console.log("init");
    this.debug = function (txt) {
        console.log(txt);
    }
    document.getElementById('shoutBoxInput').addEventListener("keypress", keyPressedFunction, false);
    this.keyPressedFunction = function(e){
        console.log("keyPressed");
    }   

    this.sendText = function() {
        var texte = document.getElementById('shoutBoxInput').value;
        if (texte=="") return;
        document.getElementById('shoutBoxInput').value =""
        this.debug("sendTexte:"+texte);     
    }
    this.receiveText = function(username, texte) {      
    }

}
var chat = new Chat();
我的问题来自:

    document.getElementById('shoutBoxInput').addEventListener("keypress", keyPressedFunction, false);
    this.keyPressedFunction = function(e){
错误未捕获引用错误:未定义按键功能

如果我使用:

document.getElementById('shoutBoxInput').addEventListener("keydown", this.keyPressedFunction, true);
然后,永远不会调用keyPressedFunction


Fiddle:

在使用函数的引用之前放置函数…然后使用这个。keyPressedFunction…那么“keypress”是有效的本机js事件吗?

是的,我说过有错误,事实上最重要的是将事件处理程序放在末尾,检查正确的事件,如果函数位于以下位置,则使用此选项:

var Chat = function() {
    console.log("init");
    this.debug = function (txt) {
        console.log(txt);
    }

    this.keyPressedFunction = function(e){
        console.log("keyPressed");
    }   

    this.sendText = function() {
        var texte = document.getElementById('shoutBoxInput').value;
        if (texte=="") return;
        document.getElementById('shoutBoxInput').value =""
        this.debug("sendTexte:"+texte);     
    }
    this.receiveText = function(username, texte) {      
    }
    // place this at the end
    document.getElementById('shoutBoxInput').addEventListener("keydown", this.keyPressedFunction, false);
}
var chat = new Chat();

在使用引用之前放置函数…然后使用此.keyPressedFunction…那么“keypress”是有效的本机js事件吗?

是的,我说过有错误,事实上最重要的是将事件处理程序放在末尾,检查正确的事件,如果函数位于以下位置,则使用此选项:

var Chat = function() {
    console.log("init");
    this.debug = function (txt) {
        console.log(txt);
    }

    this.keyPressedFunction = function(e){
        console.log("keyPressed");
    }   

    this.sendText = function() {
        var texte = document.getElementById('shoutBoxInput').value;
        if (texte=="") return;
        document.getElementById('shoutBoxInput').value =""
        this.debug("sendTexte:"+texte);     
    }
    this.receiveText = function(username, texte) {      
    }
    // place this at the end
    document.getElementById('shoutBoxInput').addEventListener("keydown", this.keyPressedFunction, false);
}
var chat = new Chat();

让我们从问题开始,然后讨论代码的危险之处

问题是,当您调用
addEventListener
时,
此.keyPressedEvent
尚不存在:

// this.keyPressedFunction doesn't exist...so you are registering a 'keypress'
// event to undefined.
document.getElementById('shoutBoxInput').addEventListener("keypress",
    keyPressedFunction, false);
// now you define this.keyPressedFunction
this.keyPressedFunction = function(e){
    console.log("keyPressed");
}
// so this is where you should be attaching it to the event
您可能在考虑JavaScript的托管机制,并认为“啊,
this.keyPressedFunction
定义被提升到这个函数的顶部,因此它可用于分配。”但提升仅适用于变量和函数定义;您所做的是将匿名函数分配给成员属性,因此提升不适用

现在来谈谈危险的问题:

当使用方法(对象的函数属性)进行回调时,调用该回调时,
this
的含义将丢失。(我知道您当前没有在回调中使用
this
,但您可能最终会使用!)换句话说,当按下一个键,并调用
keyPressedFunction
时,
this
的值将不是您期望的值。结果是,您必须非常小心地将方法分配给回调或事件。如果你想这样做,你必须使用。以下是按照正确顺序重新编写的代码,并使用
bind

this.keyPressedFunction = function(e){
    console.log("keyPressed");
}
document.getElementById('shoutBoxInput').addEventListener("keypress",
    this.keyPressedFunction.bind(this), false);

让我们从问题开始,然后讨论代码的危险之处

问题是,当您调用
addEventListener
时,
此.keyPressedEvent
尚不存在:

// this.keyPressedFunction doesn't exist...so you are registering a 'keypress'
// event to undefined.
document.getElementById('shoutBoxInput').addEventListener("keypress",
    keyPressedFunction, false);
// now you define this.keyPressedFunction
this.keyPressedFunction = function(e){
    console.log("keyPressed");
}
// so this is where you should be attaching it to the event
您可能在考虑JavaScript的托管机制,并认为“啊,
this.keyPressedFunction
定义被提升到这个函数的顶部,因此它可用于分配。”但提升仅适用于变量和函数定义;您所做的是将匿名函数分配给成员属性,因此提升不适用

现在来谈谈危险的问题:

当使用方法(对象的函数属性)进行回调时,调用该回调时,
this
的含义将丢失。(我知道您当前没有在回调中使用
this
,但您可能最终会使用!)换句话说,当按下一个键,并调用
keyPressedFunction
时,
this
的值将不是您期望的值。结果是,您必须非常小心地将方法分配给回调或事件。如果你想这样做,你必须使用。以下是按照正确顺序重新编写的代码,并使用
bind

this.keyPressedFunction = function(e){
    console.log("keyPressed");
}
document.getElementById('shoutBoxInput').addEventListener("keypress",
    this.keyPressedFunction.bind(this), false);

@dmidz提供了一个正确的答案,可以解决您的问题,但是如果您的
按键功能
只需要引用
Chat()
模块中的代码,那么您不需要将它们设置为
的属性(
Chat
):


如果您这样做,那么您不必在使用函数之前声明它们,但这样做是一种很好的方式。

@dmidz提供了一个正确的答案,可以解决您的问题,但是如果您的
keyPressedFunction
只需要引用
Chat()
模块中的代码,然后您不需要将它们设置为
this
Chat
)的属性:

如果您这样做,那么您不必在使用函数之前声明它们,但这样做是一种很好的方式。

您的答案是正确的(首先),但您确实应该将代码粘贴到答案中,而不仅仅依赖JSFIDLE来保存副本。您的答案是正确的(首先)但是,您确实应该将代码粘贴到答案中,而不是仅仅依靠JSFIDLE来保存副本。