7

There are already a few Q&A regarding the class OOP is various languages.

It appears that static method is marginally faster than Instance method but the difference is insignificant in common practical usage.
ref:
Performance of using static methods vs instantiating the class containing the methods
Speed Test: Static vs Instance Methods

  • In class instance example, 2 objects are created, the original class and a clone also using new.
    (If there is a situations where multiple processes with different data need to set values and use the same class at the same time, then creating a new clone for each process would maintain data integrity.)

  • In static example, only one object is created.

Are there any benefits to consider when deciding between the two types?

For example:

// class instance
class Triple {
  
  do(n = 1) {
    return n * 3;
  }
}
const triple = new Triple();
triple.do(5); // 15



// static method
class Triple {
  
  static do(n = 1) {
    return n * 3;
  }
}
Triple.do(5); // 15

Update constructor issue
It seems that the constructor only works in class instance.
ref:
How do I use a static variable in ES6 class?

Example:

// class instance
class TriplePlus {

  constructor() {
    this.a = 10;
  }
  
  do(n = 1) {
    return (n * 3) + this.a;
  }
}
const triplePlus = new TriplePlus();
triplePlus.do(5); // 25



// static method
class TriplePlus {

  constructor() {
    this.a = 10;
  }
  
  static do(n = 1) {
    return (n * 3) + this.a;
  }
}
TriplePlus.do(5); // NaN

Update for clarification (re comments)
Please note that above are simplified concept examples. The actual class has 10s of methods. A typical example for the static in class is a set of utility methods which perform better as OOP in a single object vs multiple individual factory functions. The focus of the topic is the comparison between class Instance vs Static. The discussion about factory function alternatives is irrelevant to this topic.

static

The static keyword defines a static method for a class. Static methods aren't called on instances of the class. Instead, they're called on the class itself. These are often utility functions, such as functions to create or clone objects.

erosman
  • 7,094
  • 7
  • 27
  • 46
  • 11
    It's quite simple - if your thing has state and may be used several times without intending to share that state between all its usages, it should be a class instance. – CherryDT Aug 17 '20 at 17:43
  • 2
    Why even use a static class method in js? Just use a plain function. – pintxo Aug 17 '20 at 18:09
  • 2
    Like @pintxo said, a `class` with *only* static methods should not exist. Just use plain function instead if there is no object to work with. – Bergi Aug 17 '20 at 19:01
  • 3
    @pintxo static functions are typically used if they return an instance of the class, e.g. `Array.from()` (can be polymorphic, asynchronous, or just perform some non-trivial computation that doesn't belong in the constructor), or if they perform a task based on two or more instances of the class, e.g. `Promise.all()`. – Patrick Roberts Aug 17 '20 at 19:29
  • @PatrickRoberts the original question showed a class with __only__ a single static method which could have easily been transformed into a stand-alone function. – pintxo Aug 17 '20 at 19:33
  • @pintxo I understand that, but someone reading _"Why even use a static class method in js? Just use a plain function."_ might not realize the suggestion was contextual. – Patrick Roberts Aug 17 '20 at 19:35
  • 2
    Why is there this `NaN` example at the end? If it doesn't work, then why is it useful? – trincot Aug 17 '20 at 19:38
  • *"It appears that static method is marginally faster"*: than what? – trincot Aug 17 '20 at 19:39
  • @Bergi Classes with only static methods are useful as namespaces. E.g. the built-in `Math` class. – Barmar Aug 17 '20 at 19:41
  • 5
    @Barmar `Math` isn't a class, it's an object. – Patrick Roberts Aug 17 '20 at 19:43
  • @Bergi I disagree because they can still be useful to allow specialization since you can inherit from them, partially overwrite or extend functionality and use `super`. – CherryDT Aug 17 '20 at 19:48
  • @trincot More info added to answer your question – erosman Aug 17 '20 at 20:21
  • @CherryDT You can do the same with plain objects. No need to use a `class` for that. Do not use `class` syntax if you don't plan to instantiate it with `new`. – Bergi Aug 18 '20 at 05:13
  • @erosman "*The actual class has 10s of methods. A set of utility methods which perform better as OOP in a single object vs multiple individual factory functions.*" - still just use an object literal with 10 methods then, not a `class`, if you don't like to make distinct functions. Or does the `constructor` in your real code actually take parameters? – Bergi Aug 18 '20 at 05:16
  • @Bergi That would divert from the main purpose of this topic which is the comparison between 2 classes. Alternative approaches to the `class` are best suited for another topic. – erosman Aug 18 '20 at 08:35
  • @erosman "*The focus of the topic is the comparison between class Instance vs Static.*" - the simple answer to that is not to use instances if they are all the same (which they are if they don't contain state). – Bergi Aug 18 '20 at 11:49

1 Answers1

2
  1. Regarding first example:
// class instance
class Triple {

If you have no shared state (shared between methods) it is better to avoid a declaration of class. Just introduce several functions grouped by module. In other words, no OOP is needed if Function abstraction is enough.

  1. Second example
// static method
class Triple {

Here we have no state and just can not use this keyword inside static methods. In such a case class is just a namespace. Think twice. Do you really need explicit namespace (class) abstraction over a module (import/export)?

  1. Update constructor issue.

As I said before static parts can not reference non-static parts. And usage of this keyword is invalid. All non-static methods implicitly accept class instance as an argument. I mean

obj.method(arg1, arg2, arg3) is equivalent of method(obj as this, arg1, arg2. arg3)

Just to recap. The majority of cases do not need OOP and patterns. Functions and modules are more straightforward and maintainable.

  • 3
    Nitpick, you _can_ use the `this` keyword (and `super` keyword as well) inside of static methods. They just refer to the class (or base class respectively) and not an instance of it. – Patrick Roberts Aug 17 '20 at 19:58
  • Thanks for clarification. I know and it is a little bit tricky. That's why it is better to avoid such usage) – Alexander Alexandrov Aug 17 '20 at 20:01
  • Also your last paragraph is very opinionated. You don't _need_ to use _any_ paradigm, but using patterns from OOP (or functional for that matter) make code a lot simpler and more maintainable even if they're not strictly necessary. A more compelling (and directly related) argument might be explaining why using a `class` as a namespace is an antipattern in JavaScript, since in other languages (C#, Java) it's practically a requirement. – Patrick Roberts Aug 17 '20 at 20:06
  • Thank you @AlexanderAlexandrov . The examples are simplified. The discussion is about `A` vs `B`, and not how can we do `A` or `B` differently. It is not practical to post a complex `class` for this purpose so a basic simple example is used. – erosman Aug 17 '20 at 20:20
  • In terms of performance, static vs non-static is not essential. Most class-related optimizations lead to the computation of static class hierarchy. In other words, dynamic fields and methods can affect performance. I do not know good alternative to `class` (with state), cause it is a part of lang from ECMAScript2015. I believe usage of lang builtin primitives (in most cases) it is a good way to invest in the future perf. optimizations ;) – Alexander Alexandrov Aug 18 '20 at 05:26
  • And static stuff could be replaced with just a module (import/export). Of course if you have DI layer (Angular, for example) and use DI scope other than `singleton`, OOP is a broadly-used and well-known approach. – Alexander Alexandrov Aug 18 '20 at 05:26