前回の記事「vue における Web フロントエンド プロジェクトの最適化の簡単な分析 (コード付き)」では、vue における Web フロントエンド プロジェクトの最適化について学びました。 ES6 プロキシ Proxy を JS で使用する方法を次の記事で紹介しますので、見てみましょう。
プロキシ
英語の本来の意味は、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; // 报错
" は外部で読み書きされます (通常、実際には内部属性であることを示すためにアンダースコアで始まります) <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">var handler = {
get(target, key) {
invariant(key, "get");
return target[key];
},
set(target, key, value) {
invariant(key, "set");
target[key] = value;
return true;
},
};
function invariant(key, action) {
if (key[0] === "_") {
throw new Error(`Invalid attempt to ${action} private "${key}" property`);
}
}
var target = {};
var proxy = new Proxy(target, handler);
proxy._prop;
// Error: Invalid attempt to get private "_prop" property
proxy._prop = "c";
// Error: Invalid attempt to set private "_prop" property</pre><div class="contentsignin">ログイン後にコピー</div></div>
がインターセプトされました - 関数呼び出し、
、apply
操作<div class="code" style="position:relative; padding:0px; margin:0px;"><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><div class="contentsignin">ログイン後にコピー</div></div>
間違っています
ループが有効になります<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">var handler = {
has(target, key) {
if (key[0] === "_") {
return false;
}
return key in target;
},
};
var target = { _prop: "foo", prop: "foo" };
var proxy = new Proxy(target, handler);
"_prop" in proxy; // false</pre><div class="contentsignin">ログイン後にコピー</div></div>
間違っています
サイクルが有効になります<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">let stu1 = { name: "张三", score: 59 };
let stu2 = { name: "李四", score: 99 };
let handler = {
has(target, prop) {
if (prop === "score" && target[prop] < 60) {
console.log(`${target.name} 不及格`);
return false;
}
return prop in target;
},
};
let oproxy1 = new Proxy(stu1, handler);
let oproxy2 = new Proxy(stu2, handler);
"score" in oproxy1;
// 张三 不及格
// false
"score" in oproxy2;
// true
for (let a in oproxy1) {
console.log(oproxy1[a]);
}
// 张三
// 59
for (let b in oproxy2) {
console.log(oproxy2[b]);
}
// 李四
// 99</pre><div class="contentsignin">ログイン後にコピー</div></div>
Interception
Method 以上がES6プロキシのJSでのProxyの使い方(コードシェアリング)を解説した記事の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。let target = {
a: 1,
b: 2,
c: 3,
};
let handler = {
ownKeys(target) {
return ["a"];
},
};
let proxy = new Proxy(target, handler);
Object.keys(proxy);
// [ 'a' ]
推奨学習:
JS 上級チュートリアル