一文讲解JS中ES6代理Proxy用法(代码分享)
之前的文章《浅析vue中web前端项目优化(附代码)》中,给大家了解了vue中web前端项目优化。下面本篇文章给大家了解一下JS中ES6代理Proxy用法,伙伴们来看看一下。
PRoxy的概念
proxy英文原意是代理的意思,在ES6中,可以翻译为"代理器"。它主要用于改变某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程。
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的操作将直通目标对象。
对proxy操作才有拦截效果,而不是目标对象。
Proxy实例的方法
当读取不存在的属性时候,抛出错误而不是返回undefined
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;
// 100person.age = "young";
// 报错person.age = 300;
// 报错防止内部属性“\_”被外部读写(通常我们以下划线开头,表示其实内部属性)
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" propertyproxy._prop = "c";
// Error: Invalid attempt to set private "_prop" property拦截——函数调用、call、apply操作
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);
// 6proxy.call(null, 5, 6);
// 22proxy.apply(null, [7, 8]);
// 30不对...in...循环生效
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不对for...in...循环生效
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;
// truefor (let a in oproxy1) {
console.log(oproxy1[a]);
}
// 张三// 59for (let b in oproxy2) {
console.log(oproxy2[b]);
}
// 李四// 99拦截object.keys()方法
let target = {
a: 1, b: 2, c: 3,}
;
let handler = {
ownKeys(target) {
return ["a"];
}
,}
;
let proxy = new Proxy(target, handler);
Object.keys(proxy);
// [ 'a' ]本文来源RYF地址:https://es6.ruanyifeng.COM/#docs/proxy
推荐学习:JS高级教程
以上就是一文讲解JS中ES6代理Proxy用法(代码分享)的详细内容,更多请关注其它相关文章!
声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!
若转载请注明出处: 一文讲解JS中ES6代理Proxy用法(代码分享)
本文地址: https://pptw.com/jishu/592096.html
