Adsense-HeaderAd-Script


Advertisement #Header

18 Jan 2016

Understanding Javascript for Java Programmers Part3: this context inside a closure


Weirdness of Javascript Continues


?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
function Student() {
   
  var c = 1;  // local variable inside Student Constructor function
  setInterval(  function counter()
                {
                    c++;        // closure func has access to outer Student function
                    console.log(c); // logs 2 3 4 5 ... after each 1000ms
                }
                , 1000
             );
}
var s = new Student();
function Student() {
  
  var c = 1;  // local variable inside Student Constructor function

  setInterval(  function counter() 
                {
                    c++;        // closure func has access to outer Student function
                    console.log(c); // logs 2 3 4 5 ... after each 1000ms
                }
                , 1000
             );
}

var s = new Student();

In the above program the closure counter() has access to value of c variable in above Student() Constructor Function.

Weirdness is with this context
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
this.d = 100;
function Student() {
   
  this.c = 1;  // 'this' is an instance of Student itself
  this.d = 1;
  setInterval(  function counter()
                {
                    this.c++;   // closure func doesnt have access to this.c of outer function
                    console.log(this.c); // logs 'NaN' after each second
                     
                    this.d++;   // closure func have access to global this.d
                    console.log(this.d); // logs 101  102  103  104 ... after each second
                }
                , 1000
             );
}
var s = new Student();
this.d = 100;
function Student() {
  
  this.c = 1;  // 'this' is an instance of Student itself
  this.d = 1;

  setInterval(  function counter() 
                {
                    this.c++;   // closure func doesnt have access to this.c of outer function
                    console.log(this.c); // logs 'NaN' after each second
                    
                    this.d++;   // closure func have access to global this.d
                    console.log(this.d); // logs 101  102  103  104 ... after each second
                }
                , 1000
             );
}

var s = new Student();

Closure function counter() doesnt have access to outer function Student() this context but has access to global this context

Workaround

1. Assign the value of this context to a variable
2. Use the new Arrow Function


1. Assign the value of this context to a variable

 
01
02
03
04
05
06
07
08
09
10
11
12
13
14
function Student() { 
   
  this.c = 1;  // 'this' is an instance of Student itself
  var outer = this// outer is a local var in Student() that captures the instance of this context
 
  setInterval(  function counter()
                {
                    outer.c++;  // closure func now have access to this.c of outer function using
                                // by passing the value of this to outer variable
                    console.log(outer.c); // logs 2  3  4  5 ... after each second
                }
                , 1000
             );
}
 
 
function Student() {  
  
  this.c = 1;  // 'this' is an instance of Student itself 
  var outer = this;  // outer is a local var in Student() that captures the instance of this context

  setInterval(  function counter() 
                {
                    outer.c++;  // closure func now have access to this.c of outer function using 
                                // by passing the value of this to outer variable
                    console.log(outer.c); // logs 2  3  4  5 ... after each second
                }
                , 1000
             );
}

2. Use the new Arrow Function =>


 
01
02
03
04
05
06
07
08
09
10
11
12
function Student() {   
  this.c = 1;  // 'this' is an instance of Student itself
 
  setInterval(  () =>
                    {
                        this.c++;   // closure func now have access to this.c of outer function
                        console.log(this.c); // logs 2  3  4  5 ... after each second
                    }
                , 1000
             );
}
var s = new Student();
 
 
function Student() {    
  this.c = 1;  // 'this' is an instance of Student itself 

  setInterval(  () =>
                    {
                        this.c++;   // closure func now have access to this.c of outer function 
                        console.log(this.c); // logs 2  3  4  5 ... after each second
                    }
                , 1000
             );
}
var s = new Student();