ハンドラによる挙動の制御 | Proxyオブジェクト | JavaScript 超完全入門 基本から発展までのすべて

現在作成中です。今後加筆修正してまいります。
スポンサーリンク
スポンサーリンク

ハンドラによる挙動の制御とは?

ハンドラは、JavaScriptのProxyオブジェクトにおける重要な要素であり、オブジェクトの操作を動的に制御するために使用されます。通常のオブジェクト操作に対して、ハンドラはその挙動を変える「トラップ(trap)」を定義します。これにより、プロパティの読み取り、書き込み、削除、存在確認など、通常のオブジェクト操作にカスタムロジックを挿入できます。

ハンドラの基本的な仕組み

Proxyのhandlerには、さまざまなトラップ(関数)があり、それぞれ異なる操作に対して動作します。ここでは、主なトラップとその使用例を見ていきます。

基本構文

const target = {};  // 操作対象のオブジェクト
const handler = {    // 挙動を制御するハンドラ
    get: function(target, prop) {
        console.log(\`プロパティ \${prop} にアクセスしました\`);
        return target[prop];
    },
    set: function(target, prop, value) {
        console.log(\`プロパティ \${prop} に値 \${value} を設定しました\`);
        target[prop] = value;
    }
};

const proxy = new Proxy(target, handler);
proxy.name = 'Alice';  // プロパティnameに値Aliceを設定
console.log(proxy.name);  // プロパティnameにアクセスしました

この例では、getsetトラップを使って、プロパティの読み取りと書き込み時にメッセージを表示する仕組みを実装しています。

代表的なハンドラトラップの一覧

以下に、Proxyオブジェクトで使用できる主なトラップを表形式でまとめました。

トラップ名 説明 使用例
get プロパティの取得時に動作 プロパティが存在しない場合にデフォルト値を返す
set プロパティの設定時に動作 値のバリデーションを行う
has プロパティの存在確認(in演算子)時に動作 プロパティの存在を制御する
deleteProperty プロパティの削除時に動作 プロパティの削除を制限する
apply 関数の呼び出し時に動作 関数の動作をカスタマイズする

代表的なハンドラメソッドの詳細な例

getトラップの詳細な使用例

以下の例では、getトラップを使って、オブジェクトのプロパティにアクセスした際にログを出力し、プロパティが存在しない場合にデフォルト値を返す処理を行います。

const target = { name: 'Alice', age: 25 };
const handler = {
    get: function(target, prop) {
        if (prop in target) {
            return target[prop];
        } else {
            console.log(\`プロパティ \${prop} は存在しません\`);
            return 'デフォルト値';
        }
    }
};
const proxy = new Proxy(target, handler);

console.log(proxy.name);   // 出力: Alice
console.log(proxy.gender); // 出力: プロパティ gender は存在しません / デフォルト値

このgetトラップでは、プロパティが存在しない場合にエラーメッセージを出力し、指定されたデフォルト値を返すように設定しています。

setトラップの詳細な使用例

次に、setトラップを使って、プロパティに設定される値をバリデーションし、特定の条件に合わない場合はエラーを表示して設定を拒否する処理を実装します。

const target = { name: 'Alice', age: 25 };
const handler = {
    set: function(target, prop, value) {
        if (prop === 'age' && typeof value !== 'number') {
            console.log('エラー: 年齢は数値でなければなりません');
            return false;
        }
        target[prop] = value;
        return true;
    }
};
const proxy = new Proxy(target, handler);

proxy.age = 30;   // 正常に設定されます
proxy.age = '30'; // エラー: 年齢は数値でなければなりません

このsetトラップでは、ageプロパティに数値以外の値を設定しようとするとエラーメッセージが表示され、値の設定が拒否されるようになっています。

他のハンドラメソッドの活用例

deletePropertyトラップの使用例

deletePropertyトラップを使って、特定のプロパティが削除されないように制御できます。次の例では、ageプロパティの削除を防ぐ処理を追加します。

const target = { name: 'Alice', age: 25 };
const handler = {
    deleteProperty: function(target, prop) {
        if (prop === 'age') {
            console.log('エラー: ageプロパティは削除できません');
            return false;
        }
        delete target[prop];
        return true;
    }
};
const proxy = new Proxy(target, handler);

delete proxy.age;   // 出力: エラー: ageプロパティは削除できません
delete proxy.name;  // nameプロパティは正常に削除されます

このdeletePropertyトラップにより、ageプロパティの削除が防止され、エラーメッセージが表示されます。

applyトラップの使用例

最後に、applyトラップを使って関数の呼び出しを制御する例を紹介します。次の例では、関数が呼び出されるたびに引数をログに出力する処理を追加します。

function sum(a, b) {
    return a + b;
}
const handler = {
    apply: function(target, thisArg, argumentsList) {
        console.log(\`関数が呼び出されました: \${argumentsList.join(', ')}\`);
        return target(...argumentsList);
    }
};
const proxy = new Proxy(sum, handler);

console.log(proxy(5, 10));  // 出力: 関数が呼び出されました: 5, 10 / 15

このapplyトラップにより、関数が呼び出される際にログが記録され、関数の実行内容を制御できます。

まとめ

Proxyオブジェクトのハンドラによる挙動の制御は、オブジェクト操作の柔軟性を飛躍的に向上させます。各トラップを適切に使用することで、通常のオブジェクト操作に対してカスタムロジックを挿入でき、動的な制御が可能になります。ただし、パフォーマンスや挙動の複雑さに注意しつつ、効果的に活用することが重要です。

Amazonロゴ
   
ad.価格範囲を指定して商品を探せます。セールで助かる便利ツール
超完全入門
スポンサーリンク
このページをメモ、または、シェア