0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

JavaScript の class 構文を使ってシングルトンとかScalaのコンパニオンクラスを作ってみた

Posted at

はじめに

JavaScript でサラッと class 構文を使ってプログラムを書くのが好きなのですが、シングルトンを書くのがやや面倒に感じていました。
2023年6月30日現在で、ググってみたのですがあまり良さそうな例がないので作ってみることにしました。

new class S1 {
}
const s1 = new S1()

のように書けばできるわけですが new class な行をconstの行でまとめて書きたいです。

1. 無名クラスを使ったシングルトン

無名クラスをつかってまとめて書いてみました:

const s1 = new class {
    dt = "companion"
    constructor() { this.dt2 = "dt2!" }
    hoge() { return "hoge" }
    fuga() { return this["fuga1"]() }
    fuga1() { return this.dt }
}
console.assert(s1.hoge()=="hoge")
console.assert(s1.fuga()=="companion")
console.assert(s1.dt=="companion")
console.assert(s1.dt2=="dt2!")

1行短く書けていい感じです。

2. Scalaのコンパニオンオブジェクトを作りたい

Scalaのobject構文を使うとクラス名と対となるシングルトンが作れて便利です。
JavaScriptでも同様に書けると嬉しいです。
プロトタイプ周りをうまくやれば出来るはず。
objectという名前の関数を作ってObject.assingな感じで使えるようにしてみました:

function object(s,p) {
  p=p.prototype
  for (let k of Object.getOwnPropertyNames(p)) s[k] = p[k].bind(s)
  const o = new p["constructor"]()
  for(let k in o) s[k]=o[k]
  return s
}

使い方:

class App {
    dt = "classdata"
    constructor() { this.dt2 = "classdt2!" }
    app() { return this.dt }
}
object(App, class {
    dt = "companion"
    constructor() { this.dt2 = "dt2!" }
    hoge() { return "hoge" }
    fuga() { return this["fuga1"]() }
    fuga1() { return this.dt }
})
console.assert(new App().app()=="classdata")
console.assert(new App().dt2=="classdt2!")
console.assert(App.hoge()=="hoge")
console.assert(App.fuga()=="companion")
console.assert(App.dt=="companion")
console.assert(App.dt2=="dt2!")

結構 Scala と似た感じでコンパニオンオブジェクトが書けるようになりました。

object関数を使ってシングルトンクラスを作る

シングルトンしかない場合にも object 関数を使ってシングルトンが作れると良いですよね。
安心してください。以下のように書けば、シングルトンのみを作ることが出来ます:

const s = object({}, class {
    dt = "companion"
    constructor() { this.dt2 = "dt2!" }
    hoge() { return "hoge" }
    fuga() { return this["fuga1"]() }
    fuga1() { return this.dt }
})
console.assert(s.hoge()=="hoge")
console.assert(s.fuga()=="companion")
console.assert(s.dt=="companion")
console.assert(s.dt2=="dt2!")

あとから同名のクラスを作りたいときはobject({},...}{}をクラス名に変えてください。

まとめ

JavaScript の class 構文を使ってシングルトンを書く方法を考えました。
また、Scalaのコンパニオンオブジェクトと同様のシングルトンを作る方法を考えました。
コンパニオンオブジェクトを作るようにシングルトンのみを作ることもできます。
このようなテクニックを使うと短く綺麗にプログラムが書けるのでお試しください。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?