Using an object method as an event listener
I'm a C++ guy just learning JavaScript, so the fact that 'this' is bound to the calling object continues to surprise. I want to use an object method as an event listener, and want to make sure I am doing it with all the style of you JavaScript professionals.
So, to get the meth开发者_运维问答od to have it's objects 'this', so that I can access its properties in the proper context, I have written the following:
var user =
{
status: 1, // login status: 0:invalid password, 1:logged out, 2:logged in
loginName: "",
// Method called whenever the user submits a username/password via html form:
onLoginSubmit: function (event)
{
if (this != user) // called from 'form submit' callback, so call ourselves:
{
user.onLoginSubmit(event);
return;
}
}
};
I found a previous answer here: Accessing an object's property from an event listener call in Javascript, but the proposed solution is to basically create a global. Is there a cooler, more professional way to get 'this' than the previous solution or my recursive solution?
I'm assuming that when you are binding the submit handler, you are doing something like this:
form.submit(user.onLoginSubmit);
While what you have does work, the best way to do with would be to bind the submit handler so that it actually calls onLoginSubmit with the proper 'this', so that you don't need any extra logic inside the submit handler.
If you do something like this when you bind the function, then it should work.
form.submit(function(e) {
user.onLoginSubmit(e);
});
By using an anonymous function, you can still properly call the method of the user object.
If I'm misunderstanding your issue, please post a bit more code about how you are calling onLoginSubmit().
You could use closures, this should work :
function User() {
var that = this;
this.status = 1;
this.loginName = "";
this.onLoginSubmit = function (event)
{
// the variable "that" is available and references the User instance
}
}
var user = new User();
Here we use User as a constructor, so this points to the object being constructed via "new". What happens (roughly) is that the "that" variable is local to the User function, but since a function references it it stays in memory and is available to this function. You're then able to use "that" instead of "this" as a "fake" scope.
This is not something you would want to use if you have a lot of User instances, because the functions are created for each instance. The "regular" way would be to use an anonymous function like in Logan's answer.
Most (if not all) frameworks have elegant ways for handling this, but basically you either need to have the scope available in the function itself via closure, or know it when you call the function so you can do it with the right scope (by writing user.onLoginSubmit() )
Hope this kinda clear :)
edit: oh well someone posted kind of the same thing in the post you linked. Well now you have it tailored to 'user'!
Might be a little late to the party but I'll leave this for anyone interested...
I really don't like how events change context, there is already a target object in the event you can reference, so I don't know why it does?
I add the listeners like this so it doesn't happen:
addEventListener('click', (event)=>{handle(event)});
-OR-
addEventListener('click', function(event){handle(event)}); //No lamda
This way the context of your handling function stays the same and you still have the event object passed through. You can reference the target in the event to get what 'this' would have been originally. Keep in mind that 'this' will now be the context that the anonymous function was called under... should be your instance if called in a class, constructor, or method.
精彩评论