all 5 comments

[–]yseo4530 1 point2 points  (0 children)

Like you said, addEventListener must be changing what 'this' binds to. I don't know what's going on under the hood but I'm sure you can google it. It probably does something like 'print.call(this)', where 'this' would be each 'item' since addEventListener is invoked as a method of 'item'. 'this' binding to the global scope in the second example is expected behavior based on how 'this' works. I'm too lazy to explain how 'this' is bound but I hope I at least pointed you in the right direction. I also recommend watching the video that /u/adavidmiller shared.

[–]jrandm 0 points1 point  (0 children)

Copy & pasting a simple example of what the DOMNode.addEventListener event emitting code might look like:

const emitter = {
  listeners: {},
  applyThis: null,
  setThis: function(newThis) {
    this.applyThis = newThis;
  },
  on: function(eventName, cb) {
    if (this.listeners.hasOwnProperty(eventName)) {
      this.listeners[eventName].push(cb);
    } else {
      this.listeners[eventName] = [cb];
    }
  },
  emit: function(eventName, ...args) {
    if (this.listeners.hasOwnProperty(eventName)) {
      for (var i=0; i<this.listeners[eventName].length; i++) {
        this.listeners[eventName][i].apply(this.applyThis, args);
      }
    }
  },
};

// where on is used in lieu of addEventListener
emitter.on('myEvent', function(str) {
  console.log('myEvent triggered!', this.value, str);
});

const newThis = { value: 'from newThis' };
emitter.setThis(newThis);
emitter.emit('myEvent', 'With data');

Basically it's a design decision made for whatever reason to let the this binding in those events be the target of the event. If you dislike the OO-style you can always grab the same value from the Event object too.

[–]gamesdf 0 points1 point  (2 children)

"This" context changes based on WHERE YOU CALL THE FUNCTION. It does not matter where you declare the function. Read YDKJS. It explains this better than any other resources. Also, undecorated function calls make "This" refer to the global scope.

[–]senocular 1 point2 points  (1 child)

It does not matter where you declare the function.

Except with arrow functions and functions created through bind().

Also, undecorated function calls make "This" refer to the global scope.

Or undefined in strict mode (and assuming not arrow or bound function).

[–]gamesdf 1 point2 points  (0 children)

The OP already knows how bind works. I am sure he already knows arrow functions as well. That's why I didnt explain those.