Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call ES5 class method from static method

I want to call an inner function from a static function that was called without an instance, like so:

Foo.Bar = function (options) {

    Autodesk.Viewing.Extension.call(this, options);

    ...

    this.innerFunc = function innerFunc(){
      ...
    }
};

Foo.Bar.prototype.constructor =
    Foo.Bar;

Foo.Bar.SomeStaticFunc = function () {
    innerFunc();
}

Use: Foo.Bar.SomeStaticFunc();.

But I get SomeStaticFunc is not a function.

The example here uses a variable for the class, like var Foo.Bar = function (options) {... but isn't that the same as making an instance of the class like so and calling an inner function?

let x= new Foo.Bar(options);
x.innerFunc();

Is there another way to do this?

PS: I know about ES6 classes but I prefer not to migrate this class to ES6 for now because it isn't totally straight forward.

like image 610
shinzou Avatar asked Apr 18 '17 14:04

shinzou


People also ask

Can static methods call other methods?

A static method can access static methods and variables as follows: A static method can call only other static methods; it cannot call a non-static method. A static method can be called directly from the class, without having to create an instance of the class.

Can we use class in ES5?

In the ES5 version, there are no classes; a function is used to make an object directly.

How do you call a static method from a class in JavaScript?

In order to call a static method from another static method, we can use 'this' keyword. 2) this. constructor. static_method_name(); : Or by using the constructor property.

Can we call static method from non-static method JavaScript?

The static method can be used to create utility functions. We can use this keyword to call a static method within another static method. We cannot use this keyword directly to call a static method within the non-static method.


1 Answers

Well... It seems that you do not know how JavaScript works internally, so here is a quick recap. :)

  • JavaScript IS an object-oriented language. Object literals are objects, arrays are objects, functions are objects, etc.

  • JavaScript IS NOT a class-based language. You could say: "Hey, I've seen class and extends keywords in ES6!". Yes, but this is just syntactic sugar. JavaScript is not based on classes like Java, it is based on prototypes.

With ES5 syntax, there are two ways to create what you call a "class":

  • An object literal
  • A constructor function

When you use an object literal, your class looks like this:

var myClass = {
  myAttribute: "foo",
  myMethod: function () {
    return "bar";
  }
};

When you use a constructor function, your class looks like this:

function MyClass() {
  this.myAttribute = "foo";
  this.myMethod = function () {
    return "bar";
  };
}

There are of course differences between these two approaches. With the object literal, you have a sort of Singleton where properties are all static to some extent. With the constructor function, you can produce instances whose properties will be introduced by the this keyword. Example:

var myInstance = new MyClass();
console.log(myInstance);

This instance will have "myAttribute" and "myMethod" in its own properties. This means that these properties are tied to the instance. If you want to call this method, you must do this:

myInstance.myMethod();

So far so good... But there is something wrong with what we did previously. this.myMethod will be created again and again for each instance of MyClass and it is always the same. A better way to handle this is to put it in the prototype so that it can be shared by all instances:

function MyClass() {
  this.myAttribute = "foo";
}

MyClass.prototype.myMethod = function () {
  return "bar";
};

This is much better, but myMethod is still tied to MyClass instances...

Now I want to create a static method. By definition, our static method will be tied to the class, not to its instances:

MyClass.myStaticMethod = function () {
  return "baz";
};

Nice. Here, for the sake of experimentation, I want to do something like this:

MyClass.myStaticMethod = function () {
  myMethod();
};

This does not work. Why? In fact, myMethod does not exist in the given scope nor in the outer scope. myMethod has been declared inside another function (the constructor function) and it is not returned, so it is invisible from the outside. Moreover, this function has been put in the prototype of MyClass. This means that it is not available globally, but only on instances of MyClass. When you think about it, it is pretty logical. For instance, when you want to call array methods (methods in Array.prototype), it does not make sense to do that:

push('test');
reverse();
includes('a');

You must call these methods on an array (instance of Array).

[].push('test');
['foo', 'bar', 'baz'].reverse();
['a', 'b'].includes('a');
like image 166
Badacadabra Avatar answered Sep 22 '22 20:09

Badacadabra