In order to understand why we need to explicitly reference this
in Javascript classes, we first need to understand what the this
reference points to in ordinary functions.
This
In Javascript the this
keyword is always a reference to the object that called the function.
Consider the following:
const obj1 = {
foo() { console.log(this); }
}
obj1.foo(); // "this" will reference "obj1"
Nothing strange here, this
is a reference to the object where it was defined obj1
.
Now think about what would happen if we took the function foo
and "removed" it from the object. Since this
is a reference to the object that called the function, what should this
be if the function doesn't belong to an object?
const obj1 = {
foo() { console.log(this); }
}
const foo = obj1.foo;
foo(); // "this" will reference "window"
This is were things start to become strange, this
is actually a reference to the global
object. This is because everything in Javascript is an object, even the root level of a file. In the browser this global object is called the window
object.
Now consider what happens if we reattache the method to another object?
const obj1 = {
foo() { console.log(this); }
}
const foo = obj1.foo;
const obj2 = {};
obj2.foo = foo;
obj2.foo(); // "this" will reference "obj2"
The same rules apply here, since the function now belongs to an object again the this
reference points to obj2
.
Classes
Fist of all Javascript doesn't actually have classes. A js class in just a different way of writing a prototype.
Lets start by writing a simple class.
class Foo {
constructor() { console.log("I'm a Class constructor") }
log() { console.log("I'm a Class method") }
}
const obj1 = new Foo(); // I'm a Class constructor
obj1.log(); // I'm a Class method
Now lets write the same "class" as a prototype.
function Bar() {
console.log("I'm a Prototype constructor")
}
Bar.prototype = {
log() {
console.log("I'm a Prototype method")
}
}
const obj2 = new Bar(); // I'm a Prototype constructor
obj2.log(); // I'm a Prototype method
These two ways of writing inheritance (classes & prototypes) are the same thing in Javascript.
So as we can more clearly see in the prototype implementation the "class methods" are actually just an object assigned to the prototype of a function.
Now that we know about this
and about classes / prototypes
we can see that a class method is actually just a function on an object and that this
refers to the the object that called the function. So if we want to reference another function on the same object we should do so by referencing it through the this
reference.
class Aa {
methodA() {
console.log('welcome to method a')
}
methodB() {
console.log('welcome to method b')
this.methodA()
}
}
const myclass = new Aa()
myclass.methodB()