0

Let's say I have the following code:

var Obj = function() {
   this.property = 1;
   this.arr = [...] // array containing elements we want to add event listeners to
   for (...) {
      this.arr[i].addEventListener("click", this.listener, false);
   }
}

Obj.prototype.listener = function() {
   console.log( this.property ); // DOES NOT WORK! *this* does not point to Obj.
}
var a = new Obj();

How do I access object properties (and methods) within a listener? I would assume I'd need to pass it as a parameter? Is the way I'm going about this structurally wrong?

user1904218
  • 237
  • 1
  • 6

2 Answers2

1

When the function is called as an event listener, the context (this) is changed to something other that the object itself.


To resolve this, manually bind the context to the object instance in the constructor using bind(). This way, this will always point to the object instance, independent of the calling context:

var Obj = function() {
  this.property = 'foo';
  this.listener = this.listener.bind(this);
}

Obj.prototype.listener = function() {
  console.log(this.property);
}

var a = new Obj();
a.listener.call({});
TimoStaudinger
  • 41,396
  • 16
  • 88
  • 94
1

As suggested by @Tushar, you can use Function.prototype.bind() and pass this.property as parameter

<body>
  click
  <script>
    var Obj = function() {
        var obj = this;
        this.property = 1;
        this.arr = [document.body];
        for (var i = 0; i < obj.arr.length; i++) {
          obj.arr[i].addEventListener("click"
          , obj.listener.bind(obj.arr[i], obj.property), false);
        }
      }
    // note order of parameters; e.g., `prop`, `e`
    Obj.prototype.listener = function(prop, e) {
      console.log(prop, e); // `1`, `event` object
    }
    var a = new Obj();
  </script>
</body>
guest271314
  • 1
  • 15
  • 104
  • 177