the "this" context

"this" in global scope (non-function scope)

"this" in global scope (non-function scope)

in Browsers: window object
in Node:global object
Note, that in nodejs, the top-level file scope is not the global scope, as each JS file in Node is treated as a module. Ref: nodejs#globals_global.

Example


            console.log(`THIS in global scope:`);
            console.dir(this);
        

            <!DOCTYPE html>
            <html lang="en">
            <head>
                <meta charset="UTF-8">
                <title>thisInGlobalScope </title>
            </head>
            <body>
                <script src="thisInGlobalScope.js"></script>
            </body>
            </html>
        

"this" in function call context

"this" in function call context

Different ways of function invocation:

this depends on how a function is invoked!
There is various ways to invoke a function in JS:
as a function
as a method
as a constructor
with apply or call or bind
Reference: this @mdn

Invoke as a function - in non Strict Mode

this ≅ global object
in Browsers: Window
in Node:global

            function f(){
                console.log( "this in function call:", this );
            }

            f();
            // Window
        

Invoke as a function - in Strict Mode

this = undefined

            "use strict";
            function f(){
                console.log( "this in strict function call:", this );
            }

            f();
            // undefined
        

more on Strict Mode: MDN JavaScript Reference

Invoke as a method

this = the object the method is called on


            var obj = {
                foo: function(){
                    console.log(`this = ${this}`);
                }
            };

            obj.foo();
            // this = [object Object]
        

Invoke as a constructor

this = the object being constructed


           function Constructor(id){
               this.id = id;
               console.log(`this = ${this}`);
           };

           var obj1 = new Constructor(1);

           // this = [object Object]
       

example

in method call this will be bound to the object, as well


        function Constructor(id){
               this.id = id;
               console.log(`this in constructor: ${this}`);

               this.showID = function(){
                   console.log(`ID: ${id}`);
                   console.log(`this in a method: ${this}`);
               }
           };

           var obj1 = new Constructor(1);
           obj1.showID();
       

"this" in DOM event handler

"this" in DOM event handler

When a function is used as an event handler, its this is set to the element on which the listener is placed

            const btn = document.querySelector("button");

            btn.addEventListener('click', function(event) {
                console.dir(this);
            })

            // OUTPUT: button
        

the "this" Pitfall and "that" Solution

the "this" Pitfall and "that" Solution

the problem

the "that" solution

apply(), call() and bind() function methods

apply(), call() and bind() function methods

Invoke with apply()


            func.apply(thisArg, [argsArray])
        
The apply() method calls a function with a given 'this' value, and arguments provided as an array
the this value inside function func will be equal to the object passed by thisArg argument.The other arguments are passed as an array to the function being called.

            function update(name, age){
                this.name = name;
                this.age = age;
            }

            let maria = {name: "Maria", age:18};
            console.log("maria before", maria);

            update.apply(maria, ["Maria Ivanova", 23]);
            console.log("maria after", maria);
        

Invoke with call()


           func.call(thisArg, arg1, ... , argN)
       
The call() method calls a function with a given 'this' value, and arguments provided individually.
the this value inside function func will be equal to the object passed by thisArg argument.The other arguments are passed as list to the function being called.

            function update(name, age){
               this.name = name;
               this.age = age;
            }

            let maria = {name: "Maria", age:18};
            console.log("maria before", maria);

            update.call(maria, "Maria Ivanova", 23);
            console.log("maria after", maria);
       

Bind a function with bind()


            func.bind(thisArg, arg1, ... , argN)
       
The bind() method creates a new function that, when called, has its this keyword set to the provided value (thisArg), with a given list of arguments preceding any provided when the new function is called

           const maria = {name: "Maria", age:18};
           function update(name, age){
               this.name = name;
               this.age = age;
           }

           console.log("maria before", maria);
           var updateMaria = update.bind(maria,"Maria Ivanova", 23);

           updateMaria();
           console.log("maria after", maria);
       

Tasks

Tasks

Task1

Fix the problem, so that we see in console numbers 1,2,3 instead of NaNs, on each click

Task2

Fix the problem in countdown function, so that we see in console the numbers 1,2,3 instead of NaN

These slides are based on

customised version of

Hakimel's reveal.js

framework