Proxy

  • 1. 前言
  • 2. 使用
  • 3. Proxy 实例方法
    • 1. get()方法
    • 2. set()方法
    • 3. apply()方法
  • 4. 为什么要存在Proxy?
    • 两者对比

1. 前言

es6中全新设计了一个叫Proxy的类型,Proxy这个词的原意是代理,用在这里表示由它来”代理“某些操作,可以译为”代理器“,可以这样理解:在目标对象之前架设一层"拦截",外界对该对象的访问,都必须先通过这层拦截

举个简单的例子

比如茅台酒的代理,有了这个代理,我们就不能直接从茅台公司拿酒,必须通过这个代理

代理说多少钱,就是多少钱,代理说没有就没有

Proxy 代理的是一个对象,这个对象被代理之后,我们就不能直接访问这个对象了,必须通过代理访问。

比如像获取某个属性的值,代理说没有就没有,代理想给你返回啥值就返回啥值

Proxy就是专门为对象设置访问代理器的,无论是读还是写都要经过代理,通过proxy就能轻松监视对象的读写过程。

2. 使用

如何使用Proxy监视对象的读写过程呢?定义一个person对象,对象当中有一个name属性和height属性,然后通过new Proxy的方式为person创建一个代理对象,此时proxy就是为person对象设置的拦截。

Proxy的构造函数需要2个参数,一个是需要代理的目标对象,另一个是代理的处理对象,在这个处理对象中可以通过get()方法监视对象属性的访问,通过set()方法监视对象设置属性的过程

const person={name:'zzz',height:185
}
const proxy=new Proxy(person,{get(){//监视对象属性的访问},set(){//监视对象设置属性的过程}
})

3. Proxy 实例方法

1. get()方法

get方法是用于拦截某个属性的读取操作,可以接受三个参数,依次为 目标对象、属性名和 proxy实例本身 (操作行为所针对的对象),最后一个参数可选。

const proxy=new Proxy(person,{get(target,propKey){// 目标对象  访问的属性名console.log(target,propKey); // {  } , name},set(){}
})
console.log(proxy.name); // zzz// 第二个例子
var person = {name: "张三"
};var proxy = new Proxy(person, {get: function(target, propKey) {if (propKey in target) {return target[propKey];} else {throw new ReferenceError("Prop name \"" + propKey + "\" does not exist.");}}
});proxy.name // "张三"
proxy.age // 抛出一个错误


get()方法正常的逻辑应该是判断代理目标对象中是否存在访问的属性名,存在就返回对应的值,不存在就返回undefined或者一个默认值

get(target,propKey){return propKey in target? target[propKey]:'default'
},//分别打印存在的属性和不存在的属性
console.log(proxy.name); //zzz
console.log(proxy.age); //default

2. set()方法

set()方法用来拦截某个属性的赋值操作,可以接受四个参数,依次为目标对象、属性名、属性值和 Proxy 实例本身,其中最后一个参数可选。

set(target,propKey,value){console.log(target,propKey,value);
}proxy.sex='男'

控制台就会打印出写入的属性和属性值

set()方法正常的逻辑应该是为代理目标设置指定属性,在设置之前先做一些数据校验,例如属性名为height,那么那么就要判断它的是否是一个数字,不是就抛出错误

set(target,propKey,value){if(propKey=== 'height'){ //判断属性名是否为heightif(!Number.isInteger(value)){//判断是否为整数throw new TypeError(`${value} is not an int`)}}target[propKey]=value
}

set方法的第四个参数receiver,指的是原始的操作行为所在的那个对象,一般情况下是proxy实例本身

const handler = {set: function(obj, prop, value, receiver) {obj[prop] = receiver;return true;}
}
const proxy = new Proxy({}, handler);
proxy.foo = 'bar';
proxy.foo === proxy;

3. apply()方法

apply方法拦截函数的调用、callapply 操作

接受三个参数,分别是 ==目标对象、目标对象的上下文对象(this) 和 目标对象的参数数组。

var handler = {apply(target, ctx, args){return Reflect.apply(...arguments);}
};

下面代码中,变量pProxy的实例,当它作为函数调用时(p()),就会被apply方法拦截,返回一个字符串。

var target = function(){ return 'I am the target'};
var handler = {apply: function(){return 'i am the proxy';}
}
var p = new Proxy(target, handler);
console.log(p());  // "i am the proxy"

4. 为什么要存在Proxy?

因为在ES6之前,我们使用Object.defineProperty()来设置监听器,来监听对象属性的获取和改写。但是如果其中存在其他的一些操作,我们是无法监测到的,所以为了解决这样一个问题,在ES6中增加了Proxy代理。Proxy可以帮助我们监听对象中的操作。

两者对比

Object.defineProperty

let info = {name: 'dmc',age: 20
}Object.defineProperty(info, 'name', {get() {console.log('get--获取info的name值')return 'dl'},set() {console.log('set--设置info的name值')}
})console.log(info.name) // get--获取info的name值   dl
info.name = 'dmc'  // set--设置info的name值

Proxy

let info = {name: 'dmc',age: 20
}let infoProxy = new Proxy(info, {get(target, key) {console.log('获取对象属性')return target[key]},set(target, key, newValue) {console.log('设置对象属性')target[key] = newValue}
})

【ES6】阮一峰ES6学习(六) Proxy相关推荐

  1. 阮一峰ES6入门读书笔记(十六):Moudle

    阮一峰ES6入门读书笔记(十六):Moudle 在 ES6 之前,社区制定了一些模块加载方案,最主要的有 CommonJS 和 AMD 两种.前者用于服务器,后者用于浏览器.ES6 在语言标准的层面上 ...

  2. 阮一峰es6电子书_ES6理解进阶【大前端高薪训练营】

    一:面向对象:类class 面向对象三大特性之封装 封装是面向对象的重要原则,它在代码中的体现主要是以下两点: 封装整体:把对象的属性和行为封装为一个整体,其中内部成员可以分为静态成员(也叫类成员)和 ...

  3. 阮一峰ES6入门读书笔记(七):运算符的拓展

    阮一峰ES6入门读书笔记(七):运算符的拓展 1. 指数运算符 ES6新增了一个指数运算符(**). 2 ** 2 // 4 2 ** 3 // 8 这个运算符的一个特点是右结合,而不是常见的左结合. ...

  4. 【ES6】阮一峰ES6学习之迭代器和for...of循环

    迭代器和for...of循环 1. 迭代器 1. 概念 2. 工作原理 3. 默认 Iterator 接口 4. 调用 Iterator 接口的场合 (1)解构赋值 (2) 扩展运算符 (3) yie ...

  5. js -- ES6(一)-- 简介(根据阮一峰ES6标准入门整理)

    目前正在学习ES6,根据阮一峰的ES6入门2,学到哪更新到哪里,都是基本的知识,复杂的目前还不会,涉及的代码都是亲自运行过的,若发现错误请指正. ES6 提供了许多新特性,但是并不是所有的浏览器都能够 ...

  6. 阮一峰 / ES6 数组的解构赋值

    目录 一.定义 二.详情讲解 1.数组解构:数组解构时数组的元素是按次序排列的,变量的取值由它的位置决定 2.对象解构:对象解构时对象的属性没有次序,变量必须与属性同名,才能取到正确的值. 三.用途 ...

  7. 实现阮一峰ES6的顶部加载条效果

    效果例子 阮一峰的ES6:http://es6.ruanyifeng.com/?search=s&x=13&y=3 html + css <style type="te ...

  8. 《ES6》(阮一峰)学习笔记

    一.简介 ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现 各大浏览器的最新版本,对 ES6 的支持可以查看kangax.github.io/compa ...

  9. 【ES6】阮一峰ES6学习之Class(一)

    Class的基本用法 1. 类的由来 2. constructor() 方法 3. 类的实例 4. 取值函数(getter)和存值函数(setter) 5. 静态方法 6. 私有方法和私有属性 7. ...

最新文章

  1. 二叉树:root==NULL和*root==NULL的区别
  2. 有效用例模式阅读笔记三
  3. mysql的单行注释_MySQL基础--会这些就够了
  4. leetcode 564,546
  5. java中手动装入新类到类装饰器_关于java:抽象装饰器类中的功能而不是装饰器...
  6. mysql报错注入实战_手工注入——MySQL手工注入实战和分析
  7. 随想录(熟练掌握uml)
  8. 江浙沪地区计算机考研高效排名,京津冀,江浙沪地区院校盘点!
  9. Android--手势及触摸事件的注意点(一)
  10. 论文笔记_S2D.23_2011-ICCV_DTAM: 稠密的实时跟踪和建图
  11. mysql 线程内存 回收_【MySQL】InnoDB后台线程与内存缓存池
  12. python修改app定位_APP自动化中三大定位工具
  13. 推荐5款精挑细选的软件,大幅提升工作效率,用一次就会爱上
  14. 傻傻弄不清楚SAP和ERP?
  15. 服务器虚拟化专用ovf模板,科学网—开放虚拟化格式规范2.0.0——OVF package - 唐宏伟的博文...
  16. C51 (矩阵键盘密码锁)
  17. BPM流程建模开发详解
  18. win7如何在桌面上加计算机,详细教您win7如何添加显示桌面图标
  19. k8s控制器——Replicaset和Deployment
  20. 通达信指标公式编写常用函数(三)——HHVBARS、LLVBARS

热门文章

  1. 神马搜索api推送收录python代码
  2. java ee是什么_java ee与java的区别是什么
  3. 九八k神曲用计算机怎么弹,常用多音字(双面打印版)
  4. java高级教程之Java继承
  5. 正交试验法生成测试用例
  6. 大疆经纬M100无人机的组装以及Onboard SDK的安装
  7. IXWebHosting的URL转向设置
  8. LLDB(六):常用命令举例
  9. 有道云协作支持Markdown了,云笔记也快了吧,哈哈
  10. 树莓派raspberry摄像头相关