JavaScript “this” references wrong object [duplica

2019-01-19 05:20发布

This question already has an answer here:

Well, this doesn't really refer to the wrong object, but I do not know how to refer to the correct one.

function someObj() {
   this.someMethod1 = function() {
      var elementBtn = document.getElementById('myBtn');
      elementBtn.onclick = function() { 
         this.someMethod2(); //I want this.someMethod2() to be called
         //...but it tries to call elementBtn.someMethod2() i believe.
      };
   };
   this.someMethod2 = function() {
      alert('OK');
   };
}

So when my myBtn is clicked I want someObj.someMethod2() to run. And I want it to be that someObj, not any other someObj. But how?!

3条回答
女痞
2楼-- · 2019-01-19 06:05

The function keyword changes scope. One solution is to maintain the reference to the "this" that you want to use.

Try the following:

function someObj() {
   var self = this;
   this.someMethod1 = function() {
      var elementBtn = document.getElementById('myBtn');
      elementBtn.onclick = function() { 
         self.someMethod2(); //NOTE self
      };
   };
   this.someMethod2 = function() {
      alert('OK');
   };
}
查看更多
劫难
3楼-- · 2019-01-19 06:09

You could use coffee script, which has a fat arrow (used for onclick function) to deal with this kind of thing, and compiles to well formed javascript. By using fat arrow, coffee script ensures the same scope as the function is defined in will be used in the callback function.

play with code here

Coffee Script

someObj = () ->
   @someMethod1 = () ->
      elementBtn = document.getElementById 'myBtn'
      elementBtn.onclick = () => 
         @someMethod2()
   this.someMethod2 = () ->
      alert 'OK'

JavaScript

var someObj;
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
someObj = function() {
  this.someMethod1 = function() {
    var elementBtn;
    elementBtn = document.getElementById('myBtn');
    return elementBtn.onclick = __bind(function() {
      return this.someMethod2();
    }, this);
  };
  return this.someMethod2 = function() {
    return alert('OK');
  };
};
查看更多
ら.Afraid
4楼-- · 2019-01-19 06:11

You might need to make a tweak like this:

function someObj() {
    var that = this;

    this.someMethod1 = function() {
        var elementBtn = document.getElementById('myBtn');
        elementBtn.onclick = function() { 
            that.someMethod2();
        };
    };
    this.someMethod2 = function() {
       alert('OK');
    };
}

"that" captures the scope you are after.

查看更多
登录 后发表回答