TheKojuEffect TheKojuEffect - 3 months ago 22
Javascript Question

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

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)?

Answer

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.