Uncaught TypeError
JavaScript らしいエラーに出会ったので残しておく。
エラーは以下。
VM213:16 Uncaught TypeError: 'set' on proxy: trap returned falsish for property 'a' at <anonymous>:16:21
setter が false を返していることが上記のエラーの原因だが、そのときに書いていたコードは false なんて返していないと思っていた。
'use strict'
const target = {
a: 0
};
const handler = {
set: function (target, prop, value, receiver) {
const res = target[prop] = value
return res
},
};
const proxy = new Proxy(target, handler);
console.log(proxy.a = 1);
console.log(proxy.a = 0);
false は返していないが 0 を返していたので、それは false を返していることになる
console.log(proxy.a = 0);
の 0 の代入で、setter は代入された 0 をそのまま返す。
setter の返り値は boolean 型なので暗黙的に boolean 型に変換される。
Javascript は 0 は false として扱うため、setter の返り値は false となり、エラーとなる。
Boolean(1)
// true
Boolean(0)
// false
Boolean(2)
// true
そもそもの誤りとして、代入したものを return で返すコードが Proxy の仕様に沿っていない、ということ。なんとなくで res
を返してたが、これがダメやな。
const handler = {
set: function (target, prop, value, receiver) {
const res = target[prop] = value
return res
},
};
どう書くべきか
MDN のサンプルでは、return の値に true を設定しているので、以下が正解の書き方になる。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Proxy
const handler = {
set: function (target, prop, value, receiver) {
target[prop] = value
return true
},
};
エラーを発生させたいパターンは、 false を return に設定すればいい。
const handler = {
set: function (target, prop, value, receiver) {
if (value === 2) {
return false
}
target[prop] = value
return true
},
};
まとめ
JavaScript の仕様に沿った書き方をしよう、っていう記事。以上!