たとえば
class A {
something() {
// ...
this.method(this.value)
// ...
}
method(value) {
// this 使わない
return !!value
}
}
this を使うメソッド something から method を呼び出すのですが method は中で this を使わず引数だけで結果が決まります
こういう関数は A の中に入れたくないので外側に出して単純な関数にします
扱うデータが A と深い関係があるなら A の static メソッドにすることもありますが A だけに関係するわけじゃないなら別用途で使いたいときに A を通したくないので関数です
こういう感じ
const fn = (value) => {
return !!value
}
class A {
something() {
// ...
fn(this.value)
// ...
}
}
いつもは特に問題もなかったのですが 今回は少し困ったことがありました
fn みたいな関数がいくつかあり 相互に呼び出していて その深い部分で this に入ってる関数を使いたいということがありました
const foo = () => {
//
}
const bar = () => {
//
}
const baz = () => {
//
const value = getValue()
//
}
class A {
something() {
// ...
foo(this.value)
// ...
}
}
これの getValue は A のメソッドを使いたいです
また 再起や循環した呼び出しがあり baz が呼び出されるまでが長いです
イメージ:
something -> foo -> bar -> foo -> bar -> bar -> baz
foo の第二引数に getValue として使いたい A のメソッドを渡して baz が呼び出されるまで foo や bar の呼び出しで常に引数として渡すことはできるのですが すごく面倒です
また baz が呼び出されるケースは少なく その中でも getValue は初期値が必要になったときだけ使うようなもの
それのためにあちこちの呼び出しで 内部で baz を使う可能性があれば引数として A のメソッドを渡していくのはとても面倒です
React などでいう Context があると助かるのですが そういうのはないただの関数呼び出しなので都度渡していくしかないです
回避するには foo, bar, baz すべてを A のメソッドにしてしまいます
baz も A のメソッドなので this を参照できます
ただ foo, bar は A に依存しないものなので気が引けます
Node.js だと AsyncLocalStorage で Context 的なことはできるのですが ブラウザでは使えないです
const { AsyncLocalStorage } = require("node:async_hooks")
const alstorage = new AsyncLocalStorage()
const foo = () => {
bar()
}
const bar = () => {
baz()
}
const baz = () => {
const getValue = alstorage.getStore()
console.log(getValue())
}
class A {
constructor(value) {
this.value = value
}
something() {
alstorage.run(() => this.getValue(), () => {
foo()
})
}
getValue() {
return this.value
}
}
new A(1).something()
new A(2).something()
1
2