How to avoid “this” refering to the DOM element, and refer to the object

萝らか妹 提交于 2019-12-01 13:27:53

Except for when using new, this in Javascript is set by according to how a function is called. Call it the right way and this will be what you want. I can't really tell what problem you're trying to solve in your question, but here's how this is determined.

  1. Calling obj.method() - this will be set to obj inside of method().
  2. Use function.call() or function.apply() to control what this will be yourself.
  3. Make a normal function call such as func() and this will be set to either the global object or undefined depending upon whether you're in strict mode.
  4. Use .bind() (in modern browsers) to create a function stub that will automatically use .apply() internally to "bind" a value of this to the execution of the function.
  5. When you call a constructor using new, this will be set to the newly created object inside the constructor.
  6. When you pass a callback function as an argument to any function call (such as addEventListener(), it is the calling function's responsibility to decide what it wants the this pointer to be set to and won't be bound to your own object. addEventListener() sets this to be the DOM object that caused the event.

For event handlers that you want to be method calls on a particular object, you have to create a way to associate the method call with the object. You can either use .bind() as specified above or use an anonymous function that can reference a saved value of this in a closure.

var self = this;
document.addEventListener('keyup', function(e) {
    self.handleKeys(e);
})

or, using .bind():

document.addEventListener('keyup', this.handleKeys.bind(this));

FYI, there's not any real functional difference between these two methods because .bind() just creates a closure and does what the first example does, but does it for you.

Simple. If a function is called as a method instead of "bare" the this always refers to the word before the last dot. So instead of:

document.getElementById('myDiv').onclick = myObject.someHandler;

// You're just passing the function here, not calling it.
// It will be called by the onclick handler so `this` is changed

do this:

document.getElementById('myDiv').onclick = function(){
    myObject.someHandler();

    // Here, you're actually calling it. So this is the word
    // before the last dot. Which is myObject
}

In more modern javascript you can of course use bind:

document.getElementById('myDiv').onclick = myObject.someHandler.bind(myObject);

The first problem in your jsfiddle is that self is a local variable for Constructor and it is not available outside of the function. What you think about the following code:

var Constructor = function(name, value) {
    var self = this;
    self.name = name;
    self.value = value;
    self.someHandler = function(e) {
        e.target.innerHTML = self.name + self.value; // self undefined    
    }
    return self;
};

var myObject = Constructor('myName', 'myValue');
document.getElementById('myDiv').onclick = myObject.someHandler;

JsFiddle -> http://jsfiddle.net/ZcG3J/4/

Is it structured as you want?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!