[ES6] Ruan Yifeng ES6 学習 (6) プロキシ

1 はじめに

es6Proxy「エージェント」と呼ばれる新しいタイプが「インターセプト」Proxy新たに設計されており、このオブジェクトへの外界のアクセスは、まずこのインターセプト層を通過する必要があります

簡単な例を挙げてください

例えば、茅台酒の代理店ですが、この代理店の場合、茅台酒会社から直接酒を入手することはできず、この代理店を経由する必要があります。

エージェントが言う金額はいくらですか、エージェントが「ノー」と言えば、その金額はありません。

Proxyプロキシはオブジェクトです。このオブジェクトがプロキシされると、このオブジェクトに直接アクセスできなくなり、プロキシ経由でアクセスする必要があります。

たとえば、特定の属性の値を取得したい場合、エージェントが値がないと言うと、その属性は存在しないことになり、エージェントは返したい値をすべて返します。

Proxyアクセス プロキシはオブジェクトに対して特別に設定されており、読み取りでも書き込みでも、プロキシを経由する必要があり、proxyオブジェクトの読み取りおよび書き込みプロセスはプロキシを通じて簡単に監視できます。

2.使用する

Proxy監視オブジェクトの読み取りおよび書き込みプロセスを使用するにはどうすればよいですか? オブジェクトを定義します。personオブジェクトにはname属性と属性がありheightnew Proxyメソッドを通じてpersonプロキシ オブジェクトを作成します。これは、オブジェクトproxypersonインターセプト セットです。

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メソッドインターセプト関数呼び出しcallapply操作

== ターゲット オブジェクト、ターゲット オブジェクトのコンテキスト オブジェクト ( 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()オブジェクト プロパティの取得と書き換えを監視するようにリスナーを設定していたためです。しかし、他の操作が入っていると監視できないため、このような問題を解決するために、ProxyES6 ではプロキシが追加されています。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
  }
})

おすすめ

転載: blog.csdn.net/Bon_nenul/article/details/128221578