"this" a reliable reference?

Asked

Viewed 180 times

13

Situation

I was riding a widget when I started to analyze a possible error, because by the tests actually occurred :

Testing

document.getElementById('teste').addEventListener('click', function(){
  n.p.call(this);
  setTimeout(function(){
    document.getElementById('result').innerHTML = 'FAIL';
    n.q.call(this);
  },2000);
});

var n = {
  options : {
    move : true,
  },
  p : function(){
    console.log(this);
    document.getElementById('result').innerHTML = this;
  },
  q : function(){
    if(this.options.move === true){
      console.log()
      document.getElementById('result').innerHTML = 'OK';
    }
  }
}

n.p();
setTimeout(function(){
  n.q();
},2000);
<p id="teste">
  teste
</p>
<div id="result">
</div>

Description

The methods of n at first should be called via n. p. (), that is function, however I remembered the method call and apply, that alter the this, to the calling object.

Doubt

  • How to reference this, whereas this is not what I expected?
  • I must always do object.var instead of this var.?

1 answer

11


William, in the following passage:

setTimeout(function(){
    document.getElementById('result').innerHTML = 'FAIL';
    n.q.call(this);
},2000);

this becomes the current function if you want to take this from the previous scope (in case a div#teste), store the same in a variable.

As to the following excerpt:

if(this.options.move === true){
    console.log()
    document.getElementById('result').innerHTML = 'OK';
}

This is the object that called the method... in a normal situation will be the own n, but when using call(this), who is calling the method is the this and this one has no property options. then go to n.options

if you need more control over your scope, use a closure or implement the interface Eventlistener

(function () {
  var teste = document.getElementById('teste');
  var result = document.getElementById('result');

  teste.addEventListener('click', function(){
    var self = this;
    n.p.call(self);
    setTimeout(function(){
      result.innerHTML = 'FAIL';
      n.q.call(self);
    },2000);
  });

  var n = {
    options : {
      move : true,
    },
    p : function(){
      console.log(this);
      result.innerHTML = this;
    },
    q : function(){
      if(n.options.move === true){
        console.log(this)
        result.innerHTML = 'OK';
      }
    }
  }

  n.p();
  setTimeout(function(){
    n.q();
  },2000);
})();
<p id="teste">
  teste
</p>
<div id="result">
</div>

an example implementing the Eventlistener interface:

var n = {
  teste: document.getElementById('teste'),
  result: document.getElementById('result'),
  options : {
    move : true,
  },
  p : function(){
    console.log(this);
    result.innerHTML = this;
  },
  q : function(){
    if(this.options.move === true){
      console.log(this)
      result.innerHTML = 'OK';
    }
  },
  handleEvent: function (event) {
    if (event.currentTarget == this.teste && event.type == "click") {
      this.exec();
    }
  },
  exec: function () {
    var self = this;
    this.p();
    setTimeout(function(){
      self.q();
    }, 2000);
  },
  init: function () {
    this.teste.addEventListener('click', this);
    this.exec();
  }
};

n.init();
<p id="teste">
  teste
</p>
<div id="result">
</div>

  • +1, very good implementation, with this confirms me that I must be careful with the this.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.