takumifukasawa’s blog

WebGL, Shader, Unity, UE4

【Javascript】素のjsでシングルトンクラスを実装する(ver. 2021/7)

jsでシングルトン的なことを実現する場合、module や import / export を使用できる環境下では例えばこのように export でインスタンスを渡すことでシングルトン的な振る舞いをさせることができます。

module.exports = new Klass();

export default new Klass();

最近、ブラウザ上で実行する素のjsでシングルトン的な機能が欲しい場面があり、クラスを使ったいわゆるシングルトンを作ってみようと思いました。

新しいAPIを試してみたいと思いMDNを漁っていたところ、private class fields が主要ブラウザ(chrome,firefox,safari)の各最新バージョンの「ほとんど」で実装されているみたいだったので使ってみることにしました。

「ほとんど」と書いたのは、 firefoxで private class fields を使うことができるのは v90 からで 2021/7/7時点のfirefox最新版v89系だとまだ使用出来ないためです。ただ、数週間のうちにv90系が出るらしいのと、今回は仕事で使う用途ではないので実験的に組み込んでみる判断にしました。

developer.mozilla.org

class Singleton {
  static #instance;
  num;

  static get instance() {
    if(!Singleton.#instance) {
      throw "no instanced";
    }
    return Singleton.#instance;
  }

  constructor(num = 0) {
    if(Singleton.#instance) {
      return Singleton.#instance;
    }
    Singleton.#instance = this;
    this.num = num;
  }

  up() {
    this.num++;
  }
}

...

const s = new Singleton();
s.up();
s.up();
console.log(s.num); // 2

...

const ss = Singleton.instance;
// ↑ const ss = new Singleton(); でも同じインスタンスが返ってくる

ss.up();
ss.up();
console.log(ss.num); // 4

ちなみに、private class field が # を使って表す理由はこの記事がとてもわかりやすかったです。「# しか使うことが出来なかった」そうです。

blog.jxck.io