How to use "this" keyword inside event listener inside a method of a class without losing access to class arguments and method arguments?

I am trying to learn the "this" keyword use in various contexts and so far all resources I found including the similar questions raised here in stackoverflow are confusing to me. These include some approach using .bind and .proxy methods. Hopefully someone has a clearer explanation on how to solve the problem described in the comment on the attached code snippet.

class Entity {
  constructor(entityArgs) {
    this.entityArgs = entityArgs;
  }
  method(methodArgs) {
    $('.button').on('click', function(event) {
      event.preventDefault();
      // Should return the button clicked. Codes seem to work
      $('#result').append('<br> clicked: ' + $(this).text() + '<br>');
      // Should return 'testMethodArg' as per below . Codes seem to work
      $('#result').append('methodArgs: ' + methodArgs + '<br>');
      // Should return 'testEntityArg' as per below. NOT WORKING - this is the problem
      $('#result').append('entityArgs: ' + this.entityArgs + '<br>');
    })
  }
}

$(function() {
  const obj = new Entity('testEntityArg');
  obj.method('testMethodArg');
})
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <title>Document</title>
</head>

<body>
  <div>
    <button id=tgtButton1 class="button">
            Button1
        </button>
  </div>
  <br>
  <div>
    <button id=tgtButton2 class="button">
            Button2
        </button>
  </div>
  <div id='result'>
  </div>
</body>

</html>

48 thoughts on “How to use "this" keyword inside event listener inside a method of a class without losing access to class arguments and method arguments?”

  1. The this keyword inside jquery’s on() function will refer to DOM element button. If you need to access the parent’s context of this, you can put it in a variable.

    class Entity {
      constructor(entityArgs) {
        this.entityArgs = entityArgs;
      }
      method(methodArgs) {
        var entity_this = this;
        $('.button').on('click', function(event) {
          console.log("this keyword from inside function: ");
          console.log(this);
          //window.this = this; // for browser's inspect/devtools only
          console.log("this keyword from parent class: ");
          console.log(entity_this);
          //window.entity_this = this; // for browser's inspect/devtools only
          event.preventDefault();
          // Should return the button clicked. Codes seem to work
          $('#result').append('<br> clicked: ' + $(this).text() + '<br>');
          // Should return 'testMethodArg' as per below . Codes seem to work
          $('#result').append('methodArgs: ' + methodArgs + '<br>');
          // Should return 'testEntityArg' as per below. NOT WORKING - this is the problem
          $('#result').append('entityArgs: ' + entity_this.entityArgs + '<br>');
        })
      }
    }
    
    $(function() {
      const obj = new Entity('testEntityArg');
      obj.method('testMethodArg');
    })
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
      <title>Document</title>
    </head>
    
    <body>
      <div>
        <button id=tgtButton1 class="button">
                Button1
            </button>
      </div>
      <br>
      <div>
        <button id=tgtButton2 class="button">
                Button2
            </button>
      </div>
      <div id='result'>
      </div>
    </body>
    
    </html>

    Note that I’m only adding window.this and window.entity_this only for debugging purpose: so that I can inspect the page and see what those objects are. Please comment those in production environment.

    Reply
  2. Flip ‘This’

    I’m about 4 months into Javascript and I’ve been making simple examples to try to get a grip on ‘this’

    When you load a webpage, the window (and all its contents) is ‘this’. Then its meaning changes in relation to how and when it’s used.

    like the button example ‘this’ is as simple as this can be

    flip = (x) => x.classList.toggle(`flipCardFlip`)
    body {
      font-family: system-ui;
      background-color: white;
    }
    
    .container {
      display: flex;
      flex-wrap: wrap;
    }
    
    .flipCard {
      width: 300px;
      height: 200px;
      perspective: 1000px;
      margin-bottom: 10px;
    }
    
    .flipCardInside {
      position: relative;
      width: 100%;
      height: 100%;
      text-align: center;
      transition: transform 0.6s;
      transform-style: preserve-3d;
    }
    
    .flipCardFlip .flipCardInside {
      transform: rotateY(180deg);
    }
    
    /* .flipCardInside {
      transform: rotateY(180deg);
    } */
    
    .front,
    .back {
      position: absolute;
      width: 100%;
      height: 100%;
      -webkit-backface-visibility: hidden;
      backface-visibility: hidden;
    }
    
    .front {
      /* background-color: dodgerblue; */
      color: whitesmoke;
      text-shadow: 0 0 2px black;
      background: radial-gradient(circle, rgba(88, 150, 250, 1) 0%, rgba(44, 55, 255, 1) 100%);
    }
    
    .back {
      /* background-color: green; */
      color: white;
      transform: rotateY(180deg);
      background: radial-gradient(circle, rgba(4, 120, 4, 1) 0%, rgba(1, 75, 5, 1) 100%);
    }
    
    .flipCardInside .back .content {
      text-align: left;
      margin-left: 20px;
      padding: 5px;
    }
    <div class="container">
    
      <div class="flipCard" onclick="flip(this)">
        <div class="flipCardInside">
          <div class="front">
            <h2>FRONT</h2>
          </div>
          <div class="back">
            <div class="content">
              <p>Back of card.</p>
              <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
            </div>
          </div>
        </div>
      </div>
    
      <div class="flipCard" onclick="flip(this)">
        <div class="flipCardInside">
          <div class="front">
            <h2>FRONT</h2>
          </div>
          <div class="back">
            <div class="content">
              <p>Back of card.</p>
              <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
            </div>
          </div>
        </div>
      </div>
    </div>
    Reply

Leave a Comment