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.