In the previous article "A brief analysis of web front-end project optimization in vue (with code)", we learned about the optimization of web front-end projects in vue. The following article will introduce you to the usage of ES6 proxy Proxy in JS. Let’s take a look.
proxy
The original English meaning is proxy, inES6
, can be translated as "agent". It is mainly used to change the default behavior of certain operations, which is equivalent to making modifications at the language level, so it is a kind of "meta programming" (meta programming
), that is, programming a programming language.
proxy
A layer of interception is built on the outer layer of the target object. Certain operations on the target object from the outside world (which operations can be intercepted will be explained later) must pass through this layer. Interception.Syntax
var proxy = new Proxy(target, handler);
Generateproxy
through the constructor, thetarget
parameter is the target object to be intercepted, and thehandler
parameter is also An object used to customize interception behavior.
Example
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); }, } );
Generally speaking, thehandle
parameter is called a configuration object. In the configuration object, you can define the operations that need to be intercepted. If the configuration object is empty, operations onproxy
will go directly to the target object.
The interception effect is only for proxy operations, not the target object.
Methods of Proxy instances
When reading non-existent properties, throw an error instead of returningundefined
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; // 抛出一个错误
Interception of reading inherited properties
let proto = new Proxy( {}, { get(target, propertyKey, receiver) { console.log("GET " + propertyKey); return target[propertyKey]; }, } ); let obj = Object.create(proto); obj.xxx; // "GET xxx"
Array reading negative index (negative index means fetching numbers backwards)
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
Implement data restrictions
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; // 报错
Prevent internal The attribute "\_
" is read and written externally (usually we start with an underscore to indicate that it is actually an internal attribute)
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
intercepted - function call,call
,apply
Operation
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
Incorrect...in...
Loop takes effect
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
Incorrectfor...in...
Cycle takes effect
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
Interceptionobject.keys()
Method
let target = { a: 1, b: 2, c: 3, }; let handler = { ownKeys(target) { return ["a"]; }, }; let proxy = new Proxy(target, handler); Object.keys(proxy); // [ 'a' ]
The source of this article is RYF address: https://es6.ruanyifeng.com/#docs /proxy
Recommended learning:JS Advanced Tutorial
The above is the detailed content of An article explaining the usage of ES6 proxy Proxy in JS (code sharing). For more information, please follow other related articles on the PHP Chinese website!