Should I use this to refer to my class in a static method like Python's @classmethod in ES2015?

In Python, you can refer to your class with the first argument from within the class method. A common way in programming is to provide an instance of yourself through a class method. For example, datetime.date.today () creates an instance of datetime.date. The class method takes over the work of initializing with date (year, month, day) and returns it.

In Python, the first argument is the caller by default It is customary to name variables self for methods and cls for class methods.

** ES2015 has a keyword equivalent to Python's @ staticmethod decorator called static, but no keyword equivalent to @ classmethod. ** ** ** How to do it **. (I'm not sure if it suits me this way)

The environment I tried was NodeJS v6.1.0. It's already supported by V8, so it doesn't go through babel in particular.

First, write a Python code example.

Example in Python

class X(object):

    @classmethod
    def create(cls):
        return cls()


class Y(X):
    pass


x = X.create()
y = Y.create()

print(isinstance(x, X))
print(isinstance(y, X))
print(isinstance(y, Y))

Execution result


True
True
True

Failure example in JavaScript (ES2015)

class X {
  static create() {
    return new X();
  }
}

class Y extends X {};

const x = X.create();
const y = Y.create();

console.log(x instanceof X);
console.log(y instanceof X);
console.log(y instanceof Y);

Execution result


true
true
false

Because new X (); has been hardcoded in X Even y, which is an instance created bycreate ()of the inherited Y, It's actually just X instead of Y.

This is not exactly what you want.

Successful example in JavaScript (ES2015) (redundant ver)

Try a verbose but simple strategy to redefine a new static method.

class X {
  static create() {
    return new this();
  }
}

class Y extends X {
  static create() {
    return new Y();
  }
}

const x = X.create();
const y = Y.create();

console.log(x instanceof X);
console.log(y instanceof X);
console.log(y instanceof Y);

Execution result


true
true
true

The result is exactly what you want. y is an instance of Y, and Y inherits from X. However, this requires redefining all class methods each time they are inherited. Therefore, it is necessary to keep track of the definition in the original class. It's inconvenient.

Successful examples in JavaScript (ES2015)

So, while doing various things, I remembered this. If self in Python corresponds to this, wouldn't the same relationship hold for class methods? Well, if you call a static method that grows from a class with a dot operator, this becomes that class ...

That's why I tried it.

class X {
  static create() {
    return new this();
  }
}

class Y extends X {};

const x = X.create();
const y = Y.create();

console.log(x instanceof X);
console.log(y instanceof X);
console.log(y instanceof Y);

Execution result


true
true
true

As expected. y is an instance of Y, and Y inherits from X. There is no need to redefine create () for Y as it is not hardcoded.

Recommended Posts

Should I use this to refer to my class in a static method like Python's @classmethod in ES2015?
I tried to create a class to search files with Python's Glob method in VBA
How to use the __call__ method in a Python class
I want to use the Django Debug Toolbar in my Ajax application
A memorandum because I stumbled on trying to use MeCab in Python
After all, what should I use to do type comparisons in Python?
[Introduction to Python] How to use class in Python?
I want to print in a comprehension
How to use __slots__ in Python class
Use Python3's Subprocess.run () in a CGI script
I tried to create a class that can easily serialize Json in Python
I didn't have to write a decorator in the class Thank you contextmanager