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.
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.
In the ES5 version, there are no classes; a function is used to make an object directly.
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.
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.
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":
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');
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With