typeof Diary

VimとかJSとか。やったことのメモ。自分のため。

JavaScriptのProxyって結構便利なのでは

Proxyオブジェクトが結構便利だったので書いてみます。

Proxy

Proxy オブジェクトは、基本的な操作 (例えばプロパティの検索、代入、列挙、関数の起動など) について独自の動作を定義するために使用します。

const proxy = new Proxy(targetObject, handler)

targetObjectに対象のオブジェクト、handlerにはそのオブジェクトに対してどうするのか、トラップと呼ばれるメソッドを定義して渡します。
よく使うであろうgetsetだけ紹介しときます。

get

const user = {
  name: 'Alice',
  age: 30
}

const proxy = new Proxy(user, {
  get(target, name) {
    if (target[name] <= 30) return 17
    return target[name]
  }
})

console.log(proxy.age) // 17

getconsole.logなど、そのプロパティにアクセスがあったとき、どうやって返すのかを定義できます。
例の場合はageが30以上なら17と表示されます。永遠のなんとやら・・・。

set

次にset。

const user = {
   name: 'Alice',
   age: null
}

const proxy = new Proxy(user, {
  set(target, name, value) {
    if (name === 'age') {
      target[name] = 17
      return true
    }
    return Reflect.set(...arguments)
  }
})

proxy.age = 30
console.log(proxy.age) // 17

例は何をいれても17になります(永遠の...)

使い所

表なりなんなり、データを一覧で表示しないといけないときとか。
条件として、nullとか空文字は-で表示してー!みたいな場合。

普通に書くと。。。

const rows = dataList.map(data => {
  return `
    <tr>
      <td>${data.A !== null ? data.A : '-'}</td>
      <td>${data.B !== null ? data.B : '-'}</td>
      <td>${data.C !== null ? data.C : '-'}</td>
      <td>${data.D !== null ? data.D : '-'}</td>
    </tr>
  `
})

// tbodyなりにrowsをappend

何も意識せず書くとこんな感じでテーブルのデータ組むと思います。
まとめるならこんな感じ。

const formatter = value => value !== null ? value : '-'
const rows = dataList.map(data => {
  return `
    <tr>
      <td>${formatter(data.A)}</td>
      <td>${formatter(data.B)}</td>
      <td>${formatter(data.C)}</td>
      <td>${formatter(data.D)}</td>
    </tr>
  `
})

やってることが単純なので、このレベルならこれで十分ですね正直。。。

Proxyを使うと、

const rows = dataList.map(data => {
  const p = new Proxy(data, {
    get(target, name) {
      if (target[name] === null) return '-'
      return target[name]
    }
  })
  return `
    <tr>
      <td>${p.A}</td>
      <td>${p.B}</td>
      <td>${p.C}</td>
      <td>${p.D}</td>
    </tr>
  `
})

HTML作ってる部分はスッキリしますね。

その他

ループでnewしまくるのが良いかどうのかってのはちょっとありそうですが、便利な機能なのでもう少し突き詰めたいところ 。

setなんかはオブジェクトの変更監視もできる気がするので、いわゆるオレオレstore的なのが作れるかも?
Vue3.0でProxyが使われてるとかそんな話を聞いたことがあるようなないような。

そもそもProxyってこんな使い方して良いのかなという疑問は残るんですが。
どうなんでしょう?