zloctb
zloctb

Reputation: 11177

Why keyword this work with static methods?

class StaticMethodCall {
      static staticMethod() {
        return 'Static method has been called';
      }
      static anotherStaticMethod() {
        return this.staticMethod() + ' from another static method';
      }
    }
    StaticMethodCall.staticMethod(); 
    // 'Static method has been called'

    StaticMethodCall.anotherStaticMethod(); 
    // 'Static method has been called from another static method'

Why this work ? I expected fatal error in this case before.

Upvotes: 3

Views: 124

Answers (4)

Karim
Karim

Reputation: 8632

To understand it better you should check the transpiled code from Babel

the scope of static functions is the same scope of the class (that compiled is a Constructor function).

Static functions are declared as properties on the Constructor function, whether normal functions are declared as properties on the Constructor.prototype and are available consequently on all the instances.

Upvotes: 1

Fullstack Guy
Fullstack Guy

Reputation: 16908

In languages like Java, the static methods belong to a class rather than an instance so when you use this inside static method you get an compilation error as the method doesn't know which instance to refer to (as there could be many instances of the class).

But the class is just a syntactic sugar for the JavaScript function object, so when you call StaticMethodCall.anotherStaticMethod(); here this will point to the context of the StaticMethodCall class object which is nothing but a function object under the hood. JavaScript functions are also objects which can have properties declared on them. So when you use a constructor function (es6 class) you could declare properties on the function object which is nothing but the static in es6.

Let me explain this way, the following code is what is happening under the hood if you transpile it to es5 through Babel:

//This is what static means in es6 class. they are properties of the constructor function
function StaticMethodCall(){ //This represents your class
}
StaticMethodCall.staticMethod = function(){
  return 'Static method has been called';
}
StaticMethodCall.anotherStaticMethod = function(){
  return this.staticMethod() + ' from another static method';
}
console.log(StaticMethodCall.staticMethod()); 
// StaticMethodCall is a reference to the class object, this points to.
console.log(StaticMethodCall.anotherStaticMethod()); 

Here when you define static methods on es6 classes the methods are added as properties of the constructor function so when you call the static method with the reference of the class StaticMethodCall this is actually pointing to that class/function object.

So this is not the same as you would expect in Java, where you cannot refer to this inside a static context as it does not know which object to refer to (as classes are not objects). In Java, classes are not actually objects like JavaScript.

Another way to verify that es6 class is actually a function is by using the typeof:

class StaticMethodCall{
}
console.log(typeof StaticMethodCall); //outputs "function"

Upvotes: 1

andy mccullough
andy mccullough

Reputation: 9551

this in JS is not the same as this in the likes of an actual OO language like Java etc. Where this in the likes of java refers to the current object of a class, in JS there are no 'classes', this in JS just refers to a current context scope, which may be, in your case, a 'static' method on a 'class', which will essentially boil down to being the current scope of a plain old object

Upvotes: 4

Pointy
Pointy

Reputation: 413702

When you call a function via a reference like someobject.property(), the this value will be set to someobject. That's a basic feature of the language. Static methods are properties of the constructor function, so when you call them via a reference to the constructor the value of this will be that function.

Upvotes: 1

Related Questions