0

I have a class and I'm relying in the "this" keyword maintaining its class context. However, when I use an event handler within the class, "this" context changes to the event. I know I can eventFunction(){}.bind(this), but I also need the event's 'this' context.

I thought of the following solution "Assigning the class 'this' as a default variable"; it seems to work, but I'm not certain this is the correct appraoch:

class A_Test {
  constructor(a, b)
  {
    this.selector = '.foam_types';
  }
  
  bind_foam_type_radios()
  {
      $(this.selector).on({
          mouseenter: this.showFoamTypeExample,
          mouseleave: this.hideFoamTypeExample,
          click: this.selectFoamType,
      }, '.foam_type_option');
  }
  
  showFoamTypeExample(e, el = this) // <-- el is being assigned the Class' "THIS"
  {
    console.log(this); // Event's "this"

    console.log(el); // Class' "this"
  }
}
var TheTest = A_Test();
TheTest.bind_foam_type_radios();
Peter Seliger
  • 11,747
  • 3
  • 28
  • 37
Jpv
  • 93
  • 3
  • 17
  • You can't really do this because there can only be one `this` (pun not intended). You can however pass the event's `this` as a regular variable. – slebetman Dec 01 '21 at 05:17
  • 1
    "*I also need the event's 'this' context.*" - just use `event.currentTarget` instead – Bergi Dec 01 '21 at 09:01

1 Answers1

1

In case of an instance method (own or prototypal) being used as event handler without explicit this binding one has to implement such a handler as arrow function in order to directly access the instantiation time's (enclosed) this context.

class A_Test {
  constructor(a, b) {
    this.selector = '.foam-types';
  }
  registerFoamTypeRadios() {
    $(this.selector).on('click', '[name="foam-type"]', this.selectFoamType);
    // mouseenter: this.showFoamTypeExample,
    // mouseleave: this.hideFoamTypeExample,
  }
  selectFoamType = (evt) => {
    const elm = evt.currentTarget;
    const srcElm = evt.target;
    console.log({ this: this, className: this.constructor.name, elm, srcElm });
  }
  showFoamTypeExample = (evt) => {}
  hideFoamTypeExample = (evt) => {}
}
var theTest = new A_Test();

theTest.registerFoamTypeRadios();
* { margin: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<fieldset class="foam-types">
  <legend>Foam Types</legend>

  <label class="foam-type-option">
    <input type="radio" name="foam-type" value="expanding"/>
    <span>Expanding Foam</span>
  </label>
  <label class="foam-type-option">
    <input type="radio" name="foam-type" value="shaving"/>
    <span>Shaving Foam</span>
  </label>
</fieldset>
Peter Seliger
  • 11,747
  • 3
  • 28
  • 37