1
class SomeClass {
  constructor() {
     this.x = 0;
  }
  getSomething(inputVal) {
   let self = this;
   return new Promise((resolve, reject) => {
    setTimeout(function(){
     if(inputVal){
       self.x = 1;
       resolve();
     }
     else{
       self.x = -1;
       reject();
     }

   }, 10);
 });
}

I am having to use a variable called self to refer to this. Is this wrong to do? if not, how else do I do it?

Deep Kakkar
  • 5,831
  • 4
  • 39
  • 75
Ranjith Ramachandra
  • 10,399
  • 14
  • 59
  • 96

2 Answers2

2

Is this wrong to do?

No, obviously that method it's not wrong, it's just a way to keep a reference to this object.

But there are some alternative ways for this problem:

1. Use bind method.

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

getSomething(inputVal) {
        return new Promise((resolve, reject) => {
            setTimeout(function(){
                if(inputVal){
                    this.x = 1;
                    resolve();
                }
                else{
                    this.x = -1;
                    reject();
                }

            }.bind(this), 10);
        });
 }

2. Use arrow functions.

Until arrow functions, every new function defined its own this value.

For instance, this can be a new object in the case of a constructor.

function Person(age){
  this.age=age;
  console.log(this);
}
let person=new Person(22);

Or this can points to the base object if the function created can be accessed like obj.getAge().

let obj={
  getAge:function(){
    console.log(this);
    return 22;
  }
}
console.log(obj.getAge());

An arrow function does not create its own this, it's just used the this value of the enclosing execution context. In the other hand, arrow function uses this of parent scope.

getSomething(inputVal) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (inputVal) {
                this.x = 1;
                resolve();
            }
            else {
                this.x = -1;
                reject();
            }

        }, 10);
    });
}
Mihai Alexandru-Ionut
  • 47,092
  • 13
  • 101
  • 128
1
class SomeClass {
    constructor() {
        this.x = 0;
    }
    getSomething(inputVal) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                if (inputVal) {
                    console.log(this.x);
                    this.x = 1;
                    resolve();
                }
                else {
                    this.x = -1;
                    reject();
                }

            }, 10);
        });
    }
}

const test = new SomeClass();
test.getSomething(true);

use arrow function in setTimeout

zabusa
  • 2,520
  • 21
  • 25