JavaScript/Proxy/revocable
Proxy.revocable()
は、後で無効化(リボーク)できるプロキシを作成するメソッドです。このメソッドは、プロキシオブジェクトとそのプロキシを無効化するための revoke
関数を含むオブジェクトを返します[1]。
構文
Proxy.revocable(target, handler)
target
: プロキシが仮想化するターゲットオブジェクト。handler
: トラップを含むオブジェクト。
例
基本的な使用例
以下のプログラムは、Proxy.revocable()
を使用して取り消し可能なプロキシを作成する基本的な例です。
const target = { message: 'hello' }; const handler = { get(target, prop, receiver) { console.log(`プロパティ "${prop}" へのアクセスが検出されました`); return Reflect.get(target, prop, receiver); } }; // 取り消し可能なプロキシを作成 const { proxy, revoke } = Proxy.revocable(target, handler); // プロキシを使用 console.log(proxy.message); // プロパティ "message" へのアクセスが検出されました、hello // プロキシを無効化 revoke(); // 無効化後のプロキシへのアクセスは例外をスローする // console.log(proxy.message); // TypeError: Cannot perform 'get' on a proxy that has been revoked
このプログラムでは、Proxy.revocable()
を使用して取り消し可能なプロキシを作成し、revoke
関数を呼び出してプロキシを無効化しています。無効化後にプロキシにアクセスしようとすると、TypeError
が発生します。
一時的なアクセス権の例
以下のプログラムは、Proxy.revocable()
を使用して一時的なアクセス権を実装する例です。
// センシティブなデータを含むオブジェクト const sensitiveData = { username: 'admin', password: 'supersecret', apiKey: '1234567890abcdef' }; // 一時的なアクセス権を付与する関数 function createTemporaryAccess(data, validTimeInMs) { const { proxy, revoke } = Proxy.revocable(data, {}); // 指定した時間後にアクセスを取り消す setTimeout(revoke, validTimeInMs); return proxy; } // 5秒間だけアクセス可能なプロキシを作成 const temporaryAccess = createTemporaryAccess(sensitiveData, 5000); // 即座にアクセス可能 console.log(temporaryAccess.username); // "admin" console.log(temporaryAccess.apiKey); // "1234567890abcdef" // 5秒後にアクセスを試みる setTimeout(() => { try { console.log(temporaryAccess.username); } catch (e) { console.log('アクセスが取り消されました:', e.message); // アクセスが取り消されました: Cannot perform 'get' on a proxy that has been revoked } }, 6000);
このプログラムでは、Proxy.revocable()
を使用して、指定した時間(この場合は5秒)だけ有効なデータへのアクセスを提供しています。時間が経過すると、プロキシは自動的に無効化されます。
APIクライアントの例
以下のプログラムは、Proxy.revocable()
を使用してAPIクライアントのセッション管理を実装する例です。
// APIクライアントのモック const apiClient = { fetchData() { return { status: 'success', data: [1, 2, 3] }; }, updateData(data) { console.log('データを更新しました:', data); return { status: 'success' }; } }; // セッション管理機能を持つAPIクライアントを作成 function createSessionClient() { let isActive = true; const { proxy, revoke } = Proxy.revocable(apiClient, { get(target, prop, receiver) { if (!isActive) { throw new Error('セッションが終了しています'); } const value = Reflect.get(target, prop, receiver); // メソッドの場合は、セッションチェックを含むラッパー関数を返す if (typeof value === 'function') { return function(...args) { if (!isActive) { throw new Error('セッションが終了しています'); } return value.apply(this, args); }; } return value; } }); // セッションを終了する関数 function endSession() { isActive = false; revoke(); } return { client: proxy, endSession }; } // セッションクライアントを作成 const { client, endSession } = createSessionClient(); // 通常の操作 console.log(client.fetchData()); // { status: 'success', data: [1, 2, 3] } client.updateData([4, 5, 6]); // データを更新しました: [4, 5, 6] // セッションを終了 endSession(); // セッション終了後の操作 try { client.fetchData(); } catch (e) { console.log('エラー:', e.message); // エラー: Cannot perform 'get' on a proxy that has been revoked }
このプログラムでは、Proxy.revocable()
を使用してセッション管理機能を持つAPIクライアントを実装しています。セッションが終了すると、クライアントのメソッドにアクセスできなくなります。
注意点
- 非可逆的: プロキシを一度無効化すると、それを元に戻すことはできません。新しいプロキシを作成する必要があります。
- 参照の保持:
revoke
関数への参照を保持していない場合、プロキシを無効化することができなくなります。 - ガベージコレクション: プロキシを無効化すると、関連するリソースがガベージコレクションの対象になります。
- エラーハンドリング: 無効化されたプロキシへのアクセスは
TypeError
をスローするため、適切なエラーハンドリングが必要です。 - ES2015+:
Proxy.revocable()
は ECMAScript 2015 (ES6) で導入されました。
脚註
- ↑ これは、一時的なアクセス権を付与し、後でそのアクセスを取り消す必要がある場合に特に有用です。