ホームページ  >  記事  >  ウェブフロントエンド  >  ES6プロキシのJSでのProxyの使い方(コードシェアリング)を解説した記事

ES6プロキシのJSでのProxyの使い方(コードシェアリング)を解説した記事

奋力向前
奋力向前転載
2021-08-27 10:23:331985ブラウズ

前回の記事「vue における Web フロントエンド プロジェクトの最適化の簡単な分析 (コード付き)」では、vue における Web フロントエンド プロジェクトの最適化について学びました。 ES6 プロキシ Proxy を JS で使用する方法を次の記事で紹介しますので、見てみましょう。

ES6プロキシのJSでのProxyの使い方(コードシェアリング)を解説した記事

プロキシの概念

プロキシ英語の本来の意味は、ES6 では「プロキシ」です。 、「エージェント」と訳せます。これは主に、特定の操作のデフォルトの動作を変更するために使用されます。これは、言語レベルで変更を行うことと同等であるため、一種の「メタ プログラミング」 (メタ プログラミング )、つまり、プログラミング言語。

proxyインターセプトのレイヤーは、ターゲット オブジェクトの外層に構築されます。外部からのターゲット オブジェクトに対する特定の操作 (どの操作がインターセプトできるかについては後で説明します) を実行する必要があります。この層を通過します。 構文

var proxy = new Proxy(target, handler);

コンストラクターを通じて proxy を生成します。target パラメーターはインターセプトするターゲット オブジェクトであり、handler パラメータは、インターセプト動作をカスタマイズするために使用されるオブジェクトでもあります。

var obj = new Proxy(
  {},
  {
    get: function (target, key, receiver) {
      console.log(`getting ${key}!`);
      return Reflect.get(target, key, receiver);
    },
    set: function (target, key, value, receiver) {
      console.log(`setting ${key}!`);
      return Reflect.set(target, key, value, receiver);
    },
  }
);

一般的に、handle パラメータは構成オブジェクトと呼ばれ、構成オブジェクトでは、必要な操作を定義できます。傍受されること。構成オブジェクトが空の場合、proxy に対する操作はターゲット オブジェクトに直接行われます。

インターセプト効果はプロキシ操作のみに適用され、ターゲット オブジェクトには適用されません。

プロキシ インスタンスのメソッド

存在しないプロパティを読み取る場合、unknown

var person = {
  name: "张三",
};

var proxy = new Proxy(person, {
  get: function (target, property) {
    if (property in target) {
      return target[property];
    } else {
      throw new ReferenceError('Property "' + property + '" does not exist.');
    }
  },
});

proxy.name; // "张三"
proxy.age; // 抛出一个错误
# を返す代わりにエラーをスローします。 ##継承されたプロパティの読み取りのインターセプト

let proto = new Proxy(
  {},
  {
    get(target, propertyKey, receiver) {
      console.log("GET " + propertyKey);
      return target[propertyKey];
    },
  }
);

let obj = Object.create(proto);
obj.xxx; // "GET xxx"

負のインデックスを読み取る配列 (負のインデックスは数値を逆方向にフェッチすることを意味します)

function createArray(...elements) {
  let handler = {
    get(target, propKey, receiver) {
      let index = Number(propKey);
      if (index < 0) {
        propKey = String(target.length + index);
      }
      return Reflect.get(target, propKey, receiver);
    },
  };

  let target = [];
  target.push(...elements);
  return new Proxy(target, handler);
}

let arr = createArray("a", "b", "c");
arr[-1]; // c

データ制限を実装します

let validator = {
  set: function (obj, prop, value) {
    if (prop === "age") {
      if (!Number.isInteger(value)) {
        throw new TypeError("The age is not an integer");
      }
      if (value > 200) {
        throw new RangeError("The age seems invalid");
      }
    }

    // 对于age以外的属性,直接保存
    obj[prop] = value;
  },
};

let person = new Proxy({}, validator);

person.age = 100;

person.age; // 100
person.age = "young"; // 报错
person.age = 300; // 报错

内部の属性「##」を防止します#\_

" は外部で読み書きされます (通常、実際には内部属性であることを示すためにアンダースコアで始まります) <pre class="brush:php;toolbar:false">var handler = { get(target, key) { invariant(key, &quot;get&quot;); return target[key]; }, set(target, key, value) { invariant(key, &quot;set&quot;); target[key] = value; return true; }, }; function invariant(key, action) { if (key[0] === &quot;_&quot;) { throw new Error(`Invalid attempt to ${action} private &quot;${key}&quot; property`); } } var target = {}; var proxy = new Proxy(target, handler); proxy._prop; // Error: Invalid attempt to get private &quot;_prop&quot; property proxy._prop = &quot;c&quot;; // Error: Invalid attempt to set private &quot;_prop&quot; property</pre> がインターセプトされました - 関数呼び出し、

call

apply操作<pre class="brush:php;toolbar:false">var twice = { apply(target, ctx, args) { return Reflect.apply(...arguments) * 2; }, }; function sum(left, right) { return left + right; } var proxy = new Proxy(sum, twice); proxy(1, 2); // 6 proxy.call(null, 5, 6); // 22 proxy.apply(null, [7, 8]); // 30</pre>間違っています

...in...

ループが有効になります<pre class="brush:php;toolbar:false">var handler = { has(target, key) { if (key[0] === &quot;_&quot;) { return false; } return key in target; }, }; var target = { _prop: &quot;foo&quot;, prop: &quot;foo&quot; }; var proxy = new Proxy(target, handler); &quot;_prop&quot; in proxy; // false</pre>間違っています

for...in...

サイクルが有効になります<pre class="brush:php;toolbar:false">let stu1 = { name: &quot;张三&quot;, score: 59 }; let stu2 = { name: &quot;李四&quot;, score: 99 }; let handler = { has(target, prop) { if (prop === &quot;score&quot; &amp;&amp; target[prop] &lt; 60) { console.log(`${target.name} 不及格`); return false; } return prop in target; }, }; let oproxy1 = new Proxy(stu1, handler); let oproxy2 = new Proxy(stu2, handler); &quot;score&quot; in oproxy1; // 张三 不及格 // false &quot;score&quot; in oproxy2; // true for (let a in oproxy1) { console.log(oproxy1[a]); } // 张三 // 59 for (let b in oproxy2) { console.log(oproxy2[b]); } // 李四 // 99</pre>Interception

object.keys()

Method<pre class="brush:php;toolbar:false">let target = { a: 1, b: 2, c: 3, }; let handler = { ownKeys(target) { return [&quot;a&quot;]; }, }; let proxy = new Proxy(target, handler); Object.keys(proxy); // [ &amp;#39;a&amp;#39; ]</pre>

この記事のソースはRYFアドレスです: https://es6 .ruanyifeng.com/#docs /proxy

推奨学習:
JS 上級チュートリアル

以上がES6プロキシのJSでのProxyの使い方(コードシェアリング)を解説した記事の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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