ホームページ >ウェブフロントエンド >jsチュートリアル >JavaScript でのプロキシの詳細な紹介 (コード例)

JavaScript でのプロキシの詳細な紹介 (コード例)

不言
不言転載
2018-12-10 17:52:199255ブラウズ

この記事では、JavaScript の Proxy について詳しく説明します (コード例)。必要な方は参考にしてください。

プロキシを使用すると、あらゆるオブジェクトのほとんどの動作を監視して干渉し、よりカスタマイズされたプログラム動作を実現できます。

使用法: 新しいプロキシ (ターゲット、ハンドラー)。

プロキシは、動作リスニング メソッドを設定することで、対応するオブジェクト上のプログラムの動作をキャプチャします。

    const obj = {};
    const proxy = new Proxy(obj, {
        // ...
    })

プロキシのコンストラクターは 2 つのパラメーターを受け取ります。最初のパラメーターは、パッケージ化する必要があるターゲット オブジェクトです。リスナーは、ターゲット オブジェクトの動作を監視するために使用されます。対応するプログラムの動作を監視します。
監視プロパティ、パラメータ、監視内容

#Listen Objext.setPrototypeOf() の呼び出し #isExtensible#preventExtensions(target)Objext.preventExtensions() の読み取りを聞く (target, prop) #defineProperty(ターゲット、プロパティ、記述子)Object.defineProperty()の呼び出しをリッスンしますプロキシ ハンドラの has listen メソッドを定義して、in ステートメントを通じてリスニング プログラムをチェックできます。文字列または数値がプロキシのターゲット オブジェクト内のプロパティのプロパティ キーであるかどうかを確認するプロシージャです。
const p = new Proxy({}, {
    has(target, prop){
        console.log(`Checking "${prop}" is in the target or not`);
        return true;
    }
})

console.log('foo' in p);
// Checking "foo" is in the target or not
// true
属性値 リスナーパラメータ 監視内容
has (target, prop) ステートメントでのモニタリングの使用
get (target, prop, reciver) ターゲット オブジェクトのプロパティの読み取りをリッスンします
set (target, prop, value 、受信者) ターゲット オブジェクトのプロパティ割り当てをリッスンします
deleteProperty (ターゲット, プロパティ) リッスンしますターゲット オブジェクトの削除ステートメント 削除プロパティの動作
ownKeys (target) Object.getOwnPropertyName() の読み取りをリッスンする
apply (target, thisArg, argument) ターゲット関数の呼び出し動作を (ターゲット オブジェクトとして) リッスンします
construct (target, argument, newTarget) new を使用してターゲット コンストラクターの動作を (ターゲット オブジェクトとして) リッスンしてインスタンスを生成します
getPrototypeOf (ターゲット) Objext.getPrototypeOf()の読み取りを聞いてください
setPrototypeOf (ターゲット, プロトタイプ)
(target) Objext.isExtensible() の読み取りを監視する
#getOwnPropertyDescriptor
Objext.getOwnPropertyDescriptor()の呼び出しをリッスンします
has
このリッスン メソッドについては、注意すべき点が 2 つあります。これらの 2 つの状況が発生した場合、TypeError がスローされます。

1. ターゲット オブジェクトが Object.preventExtensions() を通じて他のプログラムによって無効にされている場合 (オブジェクトは新しい属性を追加できず、読み取りや操作など、現在存在する属性に対してのみ操作できます)、削除されます。一度削除すると再定義することはできません) 関数で、チェック対象のプロパティ キーがターゲット オブジェクトに存在する場合、listen メソッドは false を返すことができません。

const obj = {foo: 1};

Object.preventExtensions(obj);

const p = new Proxy(obj, {
    has(target, prop){
        console.log(`Checking "${prop}" is in the target or not`);
        return false; 
    }
})

console.log('foo' in p);   
//抛出Uncaught TypeError:
2. チェック対象のプロパティ キーがターゲット オブジェクトに存在し、そのプロパティの構成可能な構成が false の場合、listen メソッドは false を返すことができません。

const obj = {};

Object.defineProperty(obj, 'foo', {
    configurable: false,
    value: 10
})

const p = new Proxy(obj, {
    has(target, prop){
        console.log(`Checking "${prop}" is in the target or not`);
        return false;
    }
})

console.log('foo' in p);
//抛出Uncaught TypeError:
get

ゲッターは既知のプロパティ キーのみを監視できますが、すべてのプロパティの読み取り動作を傍受することはできません。一方、プロキシは get listen メソッドを設定することで傍受して干渉できます。ターゲット オブジェクトのすべてのプロパティは、読む。

const obj = {foo: 1};
const p = new Proxy(obj, {
    get(target, prop){
        console.log(`Program is trying to fetch the property "${prop}".`);
        return target[prop];
    }
})

alert(p.foo);  // Program is trying to fetch the property "foo".
alert(p.something);    // Program is trying to fetch the property "something".
このリスニング メソッドにも注意が必要です。ターゲット オブジェクトの読み取りプロパティの構成可能プロパティと書き込み可能プロパティが両方とも false の場合、リスニング メソッドによって返される値は、ターゲット オブジェクトの元のプロパティ値と一致している必要があります。 。

const obj = {};

Object.defineProperty(obj, 'foo', {
    configurable: false,
    value: 10,
    writable: false
})

const p = new Proxy(obj, {
    get(target, prop){
        return 20;
    }
})

console.log(p.foo);

set

Šhandler.set は、ターゲット オブジェクトのすべてのプロパティ割り当て動作を監視するために使用されます。ターゲット オブジェクト自体のプロパティが書き込み可能または構成可能でない場合、set はこのプロパティの値を変更してはならず、同じ値のみを返すことができることに注意してください。それ以外の場合は、エラーが報告されます。

const obj = {};
const p = new Proxy(obj, {
    set(target, prop, value){
        console.log(`Setting value "${value}" on the key "${prop}" in the target object`);
        target[prop] = value;
        return true;
    }
})

p.foo = 1;  
// Setting value "1" on the key "foo" in the target object
apply

handler.apply 、プロキシは、ターゲット オブジェクトとしての関数の呼び出し動作を監視するための属性も提供します。

const sum = function(...args) {
  return args
    .map(Number)
    .filter(Boolean)
    .reduce((a, b) => a + b);

}

const p = new Proxy(sum, {
  apply(target, thisArg, args) {
    console.log(`Function is being called with arguments [${args.join()}] and context ${thisArg}`);
    return target.call(thisArg, ...args);
  }
})

console.log(p(1, 2, 3));
// Function is being called with arguments [1,2,3] and context undefined
// 6
construct

‗handler.construct、プロキシは、クラスをターゲット リスニング オブジェクトとして使用し、新しいステートメントを通じて新しいインスタンスを生成する動作を監視することもできます。コンストラクターについて。

class Foo{};

const p = new Proxy(Foo, {
    construct(target, args, newTarget){
        return {arguments: args}    // 这里返回的结果会是 new 所得到的实例
    }
});

const obj = new p(1, 2, 3);
console.log(obj.arguments);  // [1, 2, 3]
取り消し可能なプロキシ オブジェクトを作成します

使用法: Proxy.revocable(ターゲット, ハンドラー): (プロキシ, 取り消し)。

const obj = {foo: 10};
const revocable = Proxy.revocable(obj, {
    get(target, prop){
        return 20;
    }
})
const proxy = revocable.proxy;
console.log(proxy.foo); // 20
revocable.revoke();
console.log(proxy.foo); 
// TypeError: Cannot perform 'get' on a proxy that has been revoked
Proxy.revocable(target, handler) は 2 つの属性を持つオブジェクトを返します。プロキシの 1 つは関数によって生成された取り消し可能な Proxy オブジェクトであり、もう 1 つの revoke は関数によって生成された取り消し可能な Proxy オブジェクトです。 . Proxy オブジェクトの解除メソッド。

以上がJavaScript でのプロキシの詳細な紹介 (コード例)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。