To get started with js, how do the event handlers defined in the class access instance members?

for example, this class:

function Foo() {
    this.Field1 = "aaa";
}

Foo.prototype = {
    Start: function () {
        window.addEventListener("scroll", this._handler);
    },
    _handler: function () {
        //  Field1  this.Field1
    }
}

Please exclude ES6 schemes such as arrow function. Thank you.

Nov.23,2021

here I think it's better to use call or apply. After all, bind returns a new function;
while using call or apply is more in line with the inheritance nature of the prototype


I may know.
window.add. ('xxx', this._handler.bind (this));


Why not? just this.Field1 directly. When you call _ handler , it's someInstance._handlet but not someInstance.__proto__._handler . When you call this points to the instance instead of prototype .

the question you want to ask is not Foo._handler how to access the members of the Foo instance, but how to access the Foo instance in the eventListener that you added.

first of all, if your _ handler is only used as a callback of a time listener, then it should not access any instance members through the this keyword, that is, you should write it as a static member function, of course, you have no problem writing it as an instance member function, and the result is that you cannot access instance members through the this keyword. Why? Because when you add a time listener, you only tell the event trigger ( eventEmitter ) _ handler this callback, but not who should call the callback, and the caller ( caller ) / instance ( this ) of _ handler is determined at the time of the call, and this information will be lost if you don't tell it who the caller is when you add the listener.

The

solution is that your callback function cannot rely on the this keyword, but must use closures or get the instance you want through other channels (such as global variables). For example:

class Foo {
  constructor() {
    this.val = 'rua'
  }

  init() {
    window.addEventListener('scroll', Foo.getHandler(this))
  }

  doSomething() {
    // ...
  }

  static getHandler(instance) {
    function realHandler() {
      instance.doSomething()
      console.log(instance.val)
    }
    return realHandler
  }
}

or

class Foo {
  constructor() {
    this.val = 'rua'
  }

  init() {
    window.addEventListener('scroll', this.getHandler())
  }

  doSomething() {
    // ...
  }

  getHandler() {
    let self = this
    function realHandler() {
      self.doSomething()
      console.log(self.val)
    }
    return realHandler
  }
}

or

class Foo {
  constructor() {
    this.val = 'rua'
  }

  init() {
    window.addEventListener('scroll', this.handler.bind(this))
  }

  doSomeOtherThings() {
    this.handler()
  }

  doSomething() {
    // ...
  }

  handler() {
    this.doSomething()
    console.log(this.val)
  }
}

or

class Foo {
  constructor() {
    this.val = 'rua'
  }

  init() {
    let self = this
    window.addEventListener('scroll', function() {
      self.handler()
    })  // Equivalent to `bind`
  }

  doSomeOtherThings() {
    this.handler()
  }

  doSomething() {
    // ...
  }

  handler() {
    this.doSomething()
    console.log(this.val)
  }
}

change the this point inside the _ handler function and then call Foo () to access it, as follows:

_handler:function(){
   Foo.call(this);//Foo.apply(this);
   Foo();
   console.log(this.Field1);
}
Menu