Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to alias this in JavaScript 2015 (EcmaScript 6)? [duplicate]

In EcmaScript 5, we can alias this as var ctrl = this as shown in following snippet.

// EcmaScript 5
function BookController {
    var ctrl = this;

    ctrl.books = [];

    ctrl.getBook = getBook;

    function getBook(index) {
        return ctrl.books[index];
    }
}

Equivalent BookController in ES6 using class. I had a scenario in which getBook is called with this other than BookController. In getBook function, I want to make sure the context is always BookController so I want to alias this of BookController in ES6.

// EcmaScript 6
class BookController {

    constructor() {
        this.books = [];
    }

    getBook(index) {
        return this.books[index];
    }
}

How to alias this in JavaScript 2015 (EcmaScript 6)?

like image 591
TheKojuEffect Avatar asked Aug 28 '16 10:08

TheKojuEffect


1 Answers

Equivalent BookController in ES6 using class.

No, it's not equivalent, it's markedly different. Your class example is essentially equivalent to this ES5:

function BookController {
    this.books = [];
}
BookController.prototype.getBook = function getBook(index) {
    return this.books[index];
};

Note that getBook is defined on the prototype that will be assigned to instances when you use new BookController. But that's not what your first example does. Your first example assigns a different getBook to each instance, as an "own" (not inherited) property.

In getBook function, I want to make sure the context is always BookController so I want to alias this of BookController in ES6.

It's not an alias, it's a reference. You do it much the same way (in the constructor), but without the need of a variable:

// EcmaScript 6
class BookController {

    constructor() {
        this.books = [];
        this.getBook = index => {
            return this.books[index];
        };
    }
}

Because that's an arrow function, it closes over this.

Example:

// EcmaScript 6
class BookController {

  constructor() {
    this.books = [];
    this.getBook = index => {
      return this.books[index];
    };
  }
}

let c1 = new BookController();
c1.books.push("The Hitchhiker's Guide to the Galaxy");
let f1 = c1.getBook;

let c2 = new BookController();
c2.books.push("Do Androids Dream of Electric Sheep?");
let f2 = c2.getBook;

console.log(f1(0));
console.log(f2(0));

Note, though, that without a specific reason to do that, the normal thing is to leave management of this to the caller.

like image 139
T.J. Crowder Avatar answered Nov 14 '22 19:11

T.J. Crowder