Is there a way to refer to the class that a static method is included in without explicitly specifiying the class again. So instead of this:
class User {
static welcome = 'Hello'
static greet() {
console.log(User.welcome)
}
}
Something like this:
class User {
static welcome = 'Hello'
static greet() {
console.log(self.welcome)
}
}
A class is nothing but a function object. Static methods are nothing but function properties on that object. Whenever you call obj.method(), this refers to the object inside that function.
So if you call the method with User.greet(), this will refer to the function object User.
class User {
static get welcome() {
return 'hello';
}
static greet() {
console.log(this.welcome)
}
}
User.greet();
Inside instance methods you can refer to the class via this.constructor.
You can allways use "this":
class User {
static welcome = 'Hello';
static greet() {
alert(this.welcome)
}
}
User.greet();
But in case of static methods it will refer to type itself.
Here is what specs says about value of "this":
When the root declaration is an instance member or constructor of a
class, the ThisType references the this-type of that class.
When the root declaration is a member of an interface type, the
ThisType references the this-type of that interface.
Sadly, there is no such thing as self in JS, since this in JS is basically already a "merge" of this and self as described in other answers.
If you don't like to do this for a static call, you can actually do pretty similar thing as in PHP.
TL;DR Refer to the class by its name e.g. MyClass.myMethod()
class A {
static one () { console.log("I am one"); }
static two () { A.one(); }
}
A.one(); // Outputs/Logs: "I am one"
PHP equivalent could be something like
<?php
class A {
public static function one() { echo "I am one"; }
public static function two() { A::one(); }
}
A::two(); // Outputs: "I am one"
Bonus info: In JS, you can even do static two = () => A.one();, which is not available with arrow functions in PHP since in class static variable implies constant expression.
Related
So I have a class with some private methods with the same prefix. And I wanted to do a public
method that can call them using the prefix and a suffix with an idea like this :
class MyClass {
#privateMethod1(){
console.log("Hello");
}
#privateMethod2(){
console.log("world");
}
#privateMethod3(){
console.log("!");
}
publicMethod(...names){
names.forEach((name) => {
this.["#privateMethod"+`${name}`]();
});
}
}
let test = new MyClass();
test.publicMethod(1,2,3); // Should display "Hello world!"
But is it even possible? I tried to use objects but nothing seems to work
In python there's something like __call__ for this. Consider the following example:
class MyClass {
__call__() { return 'called!' }
}
const myType = new MyClass();
myType(); // called!
The question is what should I replace __call__ with?
I was doing some research, and most of the answers recommend __proto__, but it doesn't seem to work.
It is not possible out-of-the-box, but you can extend Function, and use the Function constructor to forward a call to __call__. If you have multiple classes that need this feature, extend Function only once into -- let's say -- a Callable class, and then inherit your other classes from that:
class Callable extends Function {
constructor() {
super("...args", "return this.__call__(...args)");
return this.bind(this);
}
}
class Class extends Callable {
__call__() { return 'called!' }
}
let inst = new Class();
console.log(inst());
Background
In JavaScript an object is callable when, and only if, it has the [[Call]] internal slot. But there is (currently) no way to give any given object this slot via JavaScript code. One must start with a function object and extend that.
Adding a constructor, inheritance
The above solution allows the constructor to define properties in the usual way: the constructed object is an instance of the class:
class Callable extends Function {
constructor() {
super("...args", "return this.__call__(...args)");
return this.bind(this);
}
}
class Class extends Callable {
constructor(data) {
super();
this.x = data;
}
__call__() { return 'called!' }
}
let inst = new Class(42);
console.log(inst instanceof Class); // true
console.log(inst.x); // 42
console.log(inst());
You can use constructor.
class Example {
constructor() {
// gets called on class initialization
}
}
Inside the constructor you can also call other methods if you want.
However this won't create an invoke function like using PHP's __invoke if that's what you meant. If that's what you're looking for then I don't know.
This question already has answers here:
JS call static method from class
(7 answers)
Closed 4 years ago.
Is it possible to access the class itself inside of a classes function:
class MyClass {
static get myFunction() { return "foo"; }
constructor() {
console.log(MyClass.myFunction); // "foo" -- it works when using its name. This is what we want but without using the name
console.log(this.myFunction); //undefined
console.log(this.prototype.myFunction); //Cannot read property 'myFunction' of undefined
}
}
new MyClass();
Is it possible to achieve the same as you do with MyClass.myFunction() and access the static methods without using the name of the class (in this case without using MyClass in this example?
Something like this.master.myFunction() (I’m just making master up here it’s obviously not called master)
JSBin: https://jsbin.com/hawituxosu/1/edit?js,console
Is that even possible? Thank you!
you can use constructor for this
Returns a reference to the Object constructor function that created the instance object
The constructor property has three purposes:
1. Get the class object.
2. Create an new instance
3. Invoke super constructor
class MyClass {
static get myFunction() { return "foo"; }
constructor() {
console.log(this.constructor.myFunction);
}
}
new MyClass();
an option you can do here is to call static method inside an instance method and call that instance method
class MyClass {
static get myFunction() { return "foo"; }
constructor() {
console.log(MyClass.myFunction); // "foo" -- whith using its name it works. This is what we want but without using the name
console.log(this.constructor.myFunction);
}
myFunction2() {
return this.constructor.myFunction();
}
}
const master = new MyClass();
master.myFunction2();
this.constructor.myFoo
The constructor property helps you here
You could work around getting to the class name using:
this.__proto__.constructor.name // MyClass
class MyClass {
static get myFunction() { return "foo"; }
constructor() {
console.log(eval(this.__proto__.constructor.name + ".myFunction")); //foo
}
}
new MyClass();
How does one access this scope with a static function of a class? Am I missing something here?
class Example {
constructor() {
this.name = 'Johan';
}
static hello(){
// How to access `this` scope here in the static
Example.name; // Undefined
this.name; // Undefined
}
}
The commenters are correct, this in the context of a static class method is the class itself.
When you create an instance of the class using new, that instance is its own this. You can access properties and methods on the instance through this.
See the examples below:
class Example {
constructor() {
this.name = 'Johan';
}
static hello(){
console.log(this);
console.log(this.name);
}
}
Example.hello(); // logs out the above class definition, followed by the name of the class itself.
let x = new Example();
console.log(x.name); // logs out 'Johan'.
x.hello(); // x does not have `hello()`. Only Example does.
class Foo {
static get bar() {
return 42;
}
get bar() {
return 21;
}
}
I am confused about static get bar() { return 42; },
what's the purpose of this code? who can give me a clear explantion?
static get bar()
is a getter which is not instance specific. It can be used without creating an instance of class Foo as given below:
alert(Foo.bar);
whereas
get bar()
is an object specific getter. It can only be used after creating object of class as given below:
var obj = new Foo();
alert(obj.bar);
static is similar to the static keyword in other programming languages(like java, .net ...etc)
when ever you have static property(method, variable) in your class that has been created only once, and shared across all your class objects instances.
For example if you want to have total users count inside of your class you can do that by using static keyword
Example:
class User {
Constructor() {
}
set name(name) {
this.name = name;
}
get name() {
return this.name;
}
static userCount;
}
when ever you create new user instances you can increment your users count.any of your users can access the userCount variable.To access static variable you cannot use this keyword.because it does not belongs to any instances.so to access static keyword use the following
User.userCount = 0;