4

I'm currently learning about prototypical inheritance in JavaScript. From what I've read so far, in es5, the this keyword refers to the context from which the function is called from.

With ES6 classes though, I've read that the 'this' value is lexically bound to the class instance. Can someone explain this to me? On a side note. I've also read that I shouldn't use the class syntax but instead use the OLOO pattern. Edit: I meant to ask a question here. Eric Elliot seems adamant not to approach oop and inheritance this way but instead use his OLOO pattern. Is he right about it? Or is his opinion full of fluff?

  • why not use the class syntax? – Alon Jan 04 '17 at 03:03
  • "*…the this keyword refers to the context from which the function is called from*". Nope. A function's *this* is bound to the current execution context (except for arrow functions, which get their *this* from the containing execution context), it is not the context. – RobG Jan 04 '17 at 03:08
  • Where did you read that? – Felix Kling Jan 04 '17 at 03:10
  • Can you provide a link to your reference for the "OLOO pattern"? – RobG Jan 04 '17 at 03:14
  • 1
    http://stackoverflow.com/questions/29788181/kyle-simpsons-oloo-pattern-vs-prototype-design-pattern – nem035 Jan 04 '17 at 03:18
  • 2
    the question being asked here doesn't show much at all in the way of research effort, and doesn't even really attempt to ask about a concrete problem. This question could be answered by at least a half dozen answers here on SO, such as http://stackoverflow.com/a/20279485/2495283, not to mention the multitude of websites that discuss endlessly the es6 specifications. – Claies Jan 04 '17 at 03:20

1 Answers1

4

Addition of classes in ES6 does not change the rules of how this gets bound. In fact, ES6 classes are just syntactic sugar on top of regular prototypal inheritance.

Classes just add some safety checks under the hood and allow for a simpler syntax.

The following two examples are essentially equivalent:

class A {
  constructor() {
    this.something = 5;
  }
}

console.log(
  new A().something // 5
)

function A() {
  if (!this instanceof A) {
    throw new TypeError("Class constructor A cannot be invoked without 'new'");
  }
  this.something = 5;
}

console.log(
  new A().something // 5
)

this does not refer to the context from which the function is called from. In most cases, the value of this is determined by how a function is called.

For example, the check above, i.e. this instanceof A essentially ensures that calling A without the new operator throws an error. This check is baked into classes.

class A {
  constructor() {
    this.something = 5;
  }
}

A() // Error!

By limiting the invocation to using the new operator, we ensure that this gets bound within classes as per the rules of using new.

When a function is used as a constructor (with the new keyword), its this is bound to the new object being constructed.

What this means is that, both when invoking a function as a constructor or instantiating a class, i.e new A(), behind the scenes JavaScript does the following (with regards to our same A example):

function A() {
  var newObjectThatWillBeThis = {};
  newObjectThatWillBeThis.something = 5;
  return newObjectThatWillBeThis;
}

As far as using OLOO pattern or the regular prototypal pattern, there is no one right way. Here's the answer by getify, inventor of OLOO, comparing the two approaches.

Community
  • 1
  • 1
nem035
  • 31,501
  • 5
  • 73
  • 88