1
0

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 3 years have passed since last update.

new Proxy() の set() の返り値は true でいい

Posted at

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 の仕様に沿った書き方をしよう、っていう記事。以上!

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?