this in JavaScript - aakash14goplani/FullStack GitHub Wiki

  • Refer this document for detail understanding of this

  • Explicit binding (using call() and apply()) takes precedence over implicit binding. Hard binding (using bind()) takes precedence over explicit binding

  • this works on the context of execution. Execution context is a concept in the language spec that—in layman's terms—roughly equates to the 'environment' a function executes in; that is, variable scope (and the scope chain, variables in closures from outer scopes), function arguments, and the value of the this object.

  • The contents in execution context depends on the way in which method is called. One of the variable/argument of that execution context is this. Anytime you write a function, you'll have this variable and value of this variable, depends on the way you call a function.

  • There are four ways of defining functions:

    1. Regular Functions

      function foo() {
         console.log(this); // window reference
      }
      foo();
      
      • value of this keyword is global object
    2. Function Expression

      var obj = {};
      obj.foo = function() {
         console.log(this); // {foo: ƒ}
      }
      obj.foo();
      
      • value of this keyword is referring to object itself
    3. Constructor Function

      function foo() {
         console.log(this); // foo {}
      }
      new foo();
      
      • value of this keyword is referring to newly created object
    4. Functions using call()

      function foo() {
         console.log(this);
      }
      foo.call(...);
      
      • value of this keyword is referring to object provided in argument of call() method
    5. Arrow functions

      const foo = () => {
         console.log(this); // window
      }
      foo();
      
      • value of this keyword is referring to the context in which the function is defined

Working of call() and apply() - Explicit Binding

  • I have a person's method that takes two parameters

    function Person(firstName, lastName) {
       this.firstName = firstName;
       this.lastName = lastName;
       this.fullName = function() {
          return this.firstName + ' ' + this.lastName;
       }
    } 
    
    new Person('aakash', 'goplani');
    
  • In the above example, we have two functions defined viz. Person() and fullName(). Both have different values for this. Person has this value set to a new Object i.e. Person {} whereas value of this for fullName() is the object on which the the function is called i.e. Person {firstName: "aakash", lastName: "goplani", fullName: ƒ}

  • Now I have Employee() function that needs to access fullName property of Person() function

    function Employee(firstName, lastName) {
       Person.call(this, firstName, lastName);
    } 
    new Employee('aakash', 'goplani').fullName(); // aakash goplani
    
    • Here this within Person will refer to Employee object and the property fullName will be invoked with Employee object reference.
  • While the syntax of this function is almost identical to that of apply(), the fundamental difference is that call() accepts an argument list, while apply() accepts a single array of arguments.


Working of bind() - Hard Binding

Stack Overflow