0

In Python3 I can use magic function __new__, which executes before class initialization. This helps me control whether new instance will be created or we will use some instance from cache.

Just a little simplified example:

class Something:
    def __new__(..., someArgument):
       # was a class with someArgument initialized somewhere before?
       # is yes, then:
           return CACHE[someArgument]
       # if no, then:
           CACHE[someArgument] = Something(someArgument)
           return CACHE[someArgument]

So, can I the same in ES6? Or how can I control class initializing in other way?

This question is not a duplicate of this one, because I'm asking whether I can find some functionality in JS, while the topic above contains a duscussion about this functionality.

Paul Lynn
  • 101
  • 11
  • Yes, you can. Look for `js factory` – Justinas Jun 05 '19 at 19:57
  • Probably the closest would be a class decorator (which is different from, and much more primitive than a Python class decorator). – thebjorn Jun 05 '19 at 20:04
  • @RandyCasburn, oh, it's not. I'm asking whether I can find some functionality in JS while topic you linked has a discussion about behaviour of functionality I looked for. It will be useful for people which is trying to get used to JS. – Paul Lynn Jun 05 '19 at 20:06
  • OK, I retracted my close vote. Here is the answer: If the `new` keyword is used to create an object in JavaScript, there is no way to short circuit that process. The only way to accomplish what you've asked about is to avoid using the `new` key word and then use one of a variety of methods (factory for instance) to accomplish your goal. I think the easiest way to learn about a language is by learning the language as it exists - not trying to get it to fit into the image of some other language. – Randy Casburn Jun 05 '19 at 20:12
  • It's a good subject to talk on, you know. I agree with you, but sometimes you just think "oh, wait, I can do %thing_name% using that language so fast, how can I accomplish the same with %other_language_name%?". And then the fun begins... – Paul Lynn Jun 05 '19 at 20:15

3 Answers3

2

As Justinas commented, you can look up about Javascript Factory.

A Javascript Factory define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.

Some places you can look it up:

Factory Method Design Pattern

Factory Functions with ES6

Calling Javascript Factory Method

I Hope it helped!

2

You can use factory function:

class Test {

}

function getInstance() {
  if (!Test._instance) {
    Test._instance = new Test();
  }

  return Test._instance;
}
Victor
  • 409
  • 3
  • 14
2

No, when a (non-derived) constructor is invoked with new (or super()) then an object is already instantiated before any custom code runs1. However, JS lets you overwrite the result value of the expression by returning an object from the constructor. You can write

const CACHE = new Map();
class Something {
    constructor(someArgument) {
        if (CACHE.has(someArgument)) return CACHE.get(someArgument);
//                                   ^^^^^^
        CACHE.set(someArgument, this);
        // initialise `this`
    }
}

That said, a factory function (or even static method) - as suggested by the other answers - is usually a more sensible solution. You'd put the cache handling code only in the constructor if you absolutely needed to enforce this.

1: it could be intercepted by the construct trap of a proxy, but you normally would not use that.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375