Search code examples
javascriptfunctionarrow-functions

Is my new object instance redefining my this parameter?


My goal is to establish “this“ as a reference to the button object. I understand that a solution to my problem would be to use an arrow function but Im curious, is the reference to “this“ redefined when creating a new object instance of button? Or is the initial click method not inheriting the “this“ reference to begin with? If it is the latter, then would the “this“ of the click method be the initial button function?

<button id=“test“> Click Me! </button>    
    <script>
        function Button( ) {     
            this.clicked = false;  
            this.click = function( ) { 
            this.clicked = true;              
            assert(button.clicked, “The button has been clicked“);             

                };         
      }
        var  button = new Button( ); 
        var  elem = document.getElementById(“test“); 
        elem.addEventListener(“click“, button.click);   

event listener fails to find click state


Solution

  • If you just pass button.click to addEventListener then you're just passing the function and it will be called with no this context.

    So you fix that you have bind the function to the object.

    You can either write the following, to bind the click function to the button object as a one-off:

    elem.addEventListener('click, button.click.bind(button));
    

    Or you can permanently bind the click function to the button object by writing the following in the constructor:

    this.click = this.click.bind(this);
    

    Or you could be economical with your syntax and combine them together like the following:

    this.click = function () {
      // ... your code here ...
    }.bind(this);
    

    function Button() {
      this.clicked = false;
      this.click = function () {
        console.log(this.secret);
      }.bind(this);
    }
    var button = new Button();
    button.secret = 'It works';
    var elem = document.getElementById('test');
    elem.addEventListener('click', button.click);
    <button id="test"> Click Me! </button>