博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
javascript ES6 Proxy
阅读量:6627 次
发布时间:2019-06-25

本文共 3892 字,大约阅读时间需要 12 分钟。

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' ]

本文来源

转载于:https://www.cnblogs.com/chuchur/p/10462310.html

你可能感兴趣的文章
【BZOJ】3832: [Poi2014]Rally
查看>>
[转]看懂ExtJS的API
查看>>
推荐15款制作 SVG 动画的 JavaScript 库
查看>>
转:CEO, CFO, CIO, CTO, CSO是什么
查看>>
andriod自定义视图
查看>>
linux下vim更改注释颜色
查看>>
在SSL / https下托管SignalR
查看>>
Using JRuby with Maven
查看>>
Netty了解与小试
查看>>
醒醒吧少年,只用Cucumber不能帮助你BDD
查看>>
一名女程序员对iOS的想法
查看>>
西班牙现新型电费退款网络诈骗 侨胞需谨防上当
查看>>
Spring Websocket实现文本、图片、声音、文件下载及推送、接收及显示(集群模式)...
查看>>
最严新规发布 网络短视频平台该如何降低违规风险? ...
查看>>
云服务器ECS出现速度变慢 以及突然断开怎么办?
查看>>
208亿背后的“秘密”
查看>>
Android系统自带样式(android:theme)解析
查看>>
全志A33开发板Linux内核定时器编程
查看>>
全栈必备 敏捷估点
查看>>
作为一名合格的JAVA架构师需要点亮哪些技能树?
查看>>