プロキシー
1 はじめに
es6
Proxy
「エージェント」と呼ばれる新しいタイプが「インターセプト」でProxy
新たに設計されており、このオブジェクトへの外界のアクセスは、まずこのインターセプト層を通過する必要があります。
簡単な例を挙げてください
例えば、茅台酒の代理店ですが、この代理店の場合、茅台酒会社から直接酒を入手することはできず、この代理店を経由する必要があります。
エージェントが言う金額はいくらですか、エージェントが「ノー」と言えば、その金額はありません。
Proxy
プロキシはオブジェクトです。このオブジェクトがプロキシされると、このオブジェクトに直接アクセスできなくなり、プロキシ経由でアクセスする必要があります。
たとえば、特定の属性の値を取得したい場合、エージェントが値がないと言うと、その属性は存在しないことになり、エージェントは返したい値をすべて返します。
Proxy
アクセス プロキシはオブジェクトに対して特別に設定されており、読み取りでも書き込みでも、プロキシを経由する必要があり、proxy
オブジェクトの読み取りおよび書き込みプロセスはプロキシを通じて簡単に監視できます。
2.使用する
Proxy
監視オブジェクトの読み取りおよび書き込みプロセスを使用するにはどうすればよいですか? オブジェクトを定義します。person
オブジェクトにはname
属性と属性がありheight
、new Proxy
メソッドを通じてperson
プロキシ オブジェクトを作成します。これは、オブジェクトproxy
のperson
インターセプト セットです。
Proxy
コンストラクターには 2 つのパラメーターが必要です。1 つはプロキシする必要があるターゲット オブジェクト、もう 1 つはプロキシの処理オブジェクトです。この処理オブジェクトでは、オブジェクトのプロパティへのアクセスは、メソッドとプロセスを通じて監視できget()
ますset()
。オブジェクトのプロパティの設定は、メソッドを通じて監視できます。
const person={
name:'zzz',
height:185
}
const proxy=new Proxy(person,{
get(){
//监视对象属性的访问
},
set(){
//监视对象设置属性的过程
}
})
3. プロキシインスタンスメソッド
1. get() メソッド
get
このメソッドはプロパティの読み取り操作をインターセプトするために使用され、次の順序で 3 つのパラメーターを受け入れることができます。ターゲット オブジェクト、属性名、proxy
インスタンス自体 (操作動作の対象となるオブジェクト)、最後のパラメータはオプションです。
const proxy=new Proxy(person,{
get(target,propKey){
// 目标对象 访问的属性名
console.log(target,propKey); // { } , name
},
set(){
}
})
console.log(proxy.name); // zzz
// 第二个例子
var person = {
name: "张三"
};
var proxy = new Proxy(person, {
get: function(target, propKey) {
if (propKey in target) {
return target[propKey];
} else {
throw new ReferenceError("Prop name \"" + propKey + "\" does not exist.");
}
}
});
proxy.name // "张三"
proxy.age // 抛出一个错误
get()
メソッドの通常のロジックは、プロキシ対象オブジェクトにアクセスされた属性名があるかどうかを判断し、存在する場合は対応する値を返し、存在しない場合はデフォルト値を返すはずですundefined
。
get(target,propKey){
return propKey in target? target[propKey]:'default'
},
//分别打印存在的属性和不存在的属性
console.log(proxy.name); //zzz
console.log(proxy.age); //default
2. set() メソッド
set()
このメソッドはプロパティの代入操作をインターセプトするために使用され、次の順序で 4 つのパラメーターを受け入れることができます。ターゲット オブジェクト、属性名、属性値、およびプロキシ インスタンス自体 (最後のパラメータはオプション)。
set(target,propKey,value){
console.log(target,propKey,value);
}
proxy.sex='男'
コンソールは、書き込まれたプロパティとプロパティ値を出力します。
set()
メソッドの通常のロジックでは、指定された属性をプロキシ ターゲットに設定し、設定する前にデータ検証を行う必要があります。たとえば、属性名が高さの場合、それが数値であるかどうかを判断する必要があります。エラーをスローする
set(target,propKey,value){
if(propKey=== 'height'){
//判断属性名是否为height
if(!Number.isInteger(value)){
//判断是否为整数
throw new TypeError(`${
value} is not an int`)
}
}
target[propKey]=value
}
set
メソッドの 4 番目のパラメーターは、receiver
元の操作動作が配置されているオブジェクト (通常はproxy
インスタンス自体)を参照します。
const handler = {
set: function(obj, prop, value, receiver) {
obj[prop] = receiver;
return true;
}
}
const proxy = new Proxy({
}, handler);
proxy.foo = 'bar';
proxy.foo === proxy;
3. apply() メソッド
apply
メソッドインターセプト関数呼び出しcall
とapply
操作
== ターゲット オブジェクト、ターゲット オブジェクトのコンテキスト オブジェクト ( this
)、およびターゲット オブジェクトのパラメータ配列の 3 つのパラメータを受け入れます。
var handler = {
apply(target, ctx, args){
return Reflect.apply(...arguments);
}
};
次のコードでは、変数はのインスタンスp
でありProxy
、関数 ( ) として呼び出されると、メソッドによってインターセプトp()
され、文字列が返されます。apply
var target = function(){
return 'I am the target'};
var handler = {
apply: function(){
return 'i am the proxy';
}
}
var p = new Proxy(target, handler);
console.log(p()); // "i am the proxy"
4. プロキシはなぜ存在するのですか?
ES6 より前では、Object.defineProperty()
オブジェクト プロパティの取得と書き換えを監視するようにリスナーを設定していたためです。しかし、他の操作が入っていると監視できないため、このような問題を解決するために、Proxy
ES6 ではプロキシが追加されています。Proxy
オブジェクト内の操作を監視するのに役立ちます。
2つを比較してください
Object.defineProperty
let info = {
name: 'dmc',
age: 20
}
Object.defineProperty(info, 'name', {
get() {
console.log('get--获取info的name值')
return 'dl'
},
set() {
console.log('set--设置info的name值')
}
})
console.log(info.name) // get--获取info的name值 dl
info.name = 'dmc' // set--设置info的name值
Proxy
let info = {
name: 'dmc',
age: 20
}
let infoProxy = new Proxy(info, {
get(target, key) {
console.log('获取对象属性')
return target[key]
},
set(target, key, newValue) {
console.log('设置对象属性')
target[key] = newValue
}
})