コンテンツへスキップ

JavaScriptのProxyを使いこなそう

by : 2018/05/07

最近、ReactやVueなどVirtualDOMを使った技術がトレンドになっています。VirtualDOMの特徴として、DOMの状態を管理から開放されて、変数を変えるだけで自動的に表示に反映される仕組みがあります。

変数の変更を感知し、表示に反映するために使われるのがProxyになります。VirtualDOMに限らず使える場面が多いオブジェクトなので、ぜひ使い方を覚えましょう。

基本的な使い方

Proxyはオブジェクトまたは配列に対してしか使えません。単なる数字や文字列では使えないので注意してください。以下はごく基本的なコードです。


const obj = {};
const p = new Proxy(obj, {
get: (target, name) => {
console.log(`(get) target : ${JSON.stringify(target)}, name: ${name}`);
return target[name];
},
set: (target, name, value) => {
console.log(`(set) target : ${JSON.stringify(target)}, name: ${name}`);
target[name] = value;
}
});
p.a = "hello";
p.a
// -> hello

view raw

index.js

hosted with ❤ by GitHub

まずProxyは既存の変数にとハンドラーを引数に取ります。


const obj = {};
const p = new Proxy(obj, handler);

view raw

index.js

hosted with ❤ by GitHub

handlerはget/setを基本としたオブジェクトになります。値を追加した時にset、アクセスした際にgetがコールされます。targetは元のオブジェクト(obj)で、nameはアクセスしようとしたメソッド名(またはキー)になります。そしてvalueとして適用しようとした値が送られます。


set: (target, name, value) => {
target[name] = value;
}

view raw

index.js

hosted with ❤ by GitHub

getはターゲットと実行するメソッド名(またはキー)が送られてきます。


set: (target, name, value) => {
target[name] = value;
}

view raw

index.js

hosted with ❤ by GitHub

配列の場合

Proxyはオブジェクトだけでなく配列にも使えます。


const ary = [];
const q = new Proxy(ary, {
get: (target, name) => {
console.log(`(get) target : ${JSON.stringify(target)}, name: ${name}`);
return target[name];
},
set: (target, name, value) => {
console.log(`(set) target : ${JSON.stringify(target)}, name: ${name}`);
target[name] = value;
}
});
q.push('a');
q.push('b');
q.push('c');
console.log(q[0]);

view raw

index.js

hosted with ❤ by GitHub

使い方はオブジェクトの時と変わりません。ただし、配列の中にオブジェクトがあった場合、そのオブジェクトの中を変えても通知されないので注意が必要です。


q.push({
a: 'b',
c: 'd'
});
// 以下は通知されません
q[3].a = 'e';

view raw

index.js

hosted with ❤ by GitHub

他のオブジェクト

他のオブジェクト(関数、クラス)などに対してもProxyが使えます。ただしクラスなどでインスタンスに対して適用したい場合は、クラスではなくインスタンスに対してProxyを適用する必要があります。


class Animal {
constructor() {
this.name = '';
}
setName(name) {
this.name = name;
}
getName() {
return this.name;
}
}
const dog = new Proxy(new Animal, {
get: (target, name) => {
console.log(`(class get) target : ${JSON.stringify(target)}, name: ${name}`);
return target[name];
},
set: (target, name, value) => {
console.log(`(class set) target : ${JSON.stringify(target)}, name: ${name}`);
target[name] = value;
}
});
dog.setName('dog');
console.log(dog.getName());

view raw

index.js

hosted with ❤ by GitHub


Proxyを使うと、データを更新した時に関連するデータや表示をまとめて更新するといったことが簡単にできます。また、値を判別して例外を出すことで入力チェックのように使うこともできます。

ぜひProxyを使って関連する処理をまとめてみてください。

From → HTML5

コメントは受け付けていません。

%d人のブロガーが「いいね」をつけました。