algojedi
algojedi

Reputation: 67

Class variable undefined inside function

Just trying to learn Angular 2+ (8 specifically) and for the life of me, I can't understand why a class variable is 'undefined' inside a class function, but accessible if I write the function with ES6 style.

I tried setting in constructor instead, but that doesn't make sense.

export class GameControlComponent implements OnInit {

    myVar;
    counter = 0; 

    constructor() {}  ngOnInit() {}

    handleClickStart() {

        this.myVar = setInterval(this.myFunc, 1500);
    }

    myFunc() {
        this.counter++;
        console.log(this.counter);  
    }
}

Once 'handleClickStart' is called, this outputs NaN every 1.5 seconds. Why???? I would have expected 1 2 3....

Implementing handleClickStart this way gives me the desired results:

handleClickStart() {    
    this.myVar = setInterval(() => {
      console.log(this.counter + 1);
      this.counter++;
    }, 1500);
}

But still can't figure out why it didn't work out the first way.

Upvotes: 3

Views: 4040

Answers (1)

Sebin Benjamin
Sebin Benjamin

Reputation: 1898

This behaviour has to do with scopes, arrow functions,this and how Javascript functions/objects work.

Functions in JavaScript run in a specific context and using this accesses the current context. this.counter in the sample code is not available/defined inside setInterval() function, so we get undefined.

Now, in Arrow functions, things are special/different. Arrow Functions always lexically bind the context (Lexical Scoping means that it uses this from the code that contains the Arrow Function.) and therefore this will refer to the originating context, ie the class.

A simpler example might make it more clear.

const obj = {
  myVar: 'foo',
  myFunc: function() { 
    console.log('Actual Variable value: ',this.myVar)  

    setTimeout(() => {
      console.log('Set timeout using Arrow function: ',this.myVar)
    }, 1000);
    setTimeout(function () {
      console.log('Set timeout using Normal function: ',this.myVar)
    }, 1000);
  }
}
obj.myFunc();

Output

Actual Variable value: foo
Set timeout using Arrow function:  foo
Set timeout using Normal function:  undefined

Read more

  1. Arrow functions
  2. this keyword

Upvotes: 6

Related Questions