【ES6】阮一峰ES6学习(六) Proxy
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
方法拦截函数的调用、call
和 apply
操作
接受三个参数,分别是 ==目标对象、目标对象的上下文对象(this
) 和 目标对象的参数数组。
var handler = {apply(target, ctx, args){return Reflect.apply(...arguments);}
};
下面代码中,变量p
是Proxy
的实例,当它作为函数调用时(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相关推荐
- 阮一峰ES6入门读书笔记(十六):Moudle
阮一峰ES6入门读书笔记(十六):Moudle 在 ES6 之前,社区制定了一些模块加载方案,最主要的有 CommonJS 和 AMD 两种.前者用于服务器,后者用于浏览器.ES6 在语言标准的层面上 ...
- 阮一峰es6电子书_ES6理解进阶【大前端高薪训练营】
一:面向对象:类class 面向对象三大特性之封装 封装是面向对象的重要原则,它在代码中的体现主要是以下两点: 封装整体:把对象的属性和行为封装为一个整体,其中内部成员可以分为静态成员(也叫类成员)和 ...
- 阮一峰ES6入门读书笔记(七):运算符的拓展
阮一峰ES6入门读书笔记(七):运算符的拓展 1. 指数运算符 ES6新增了一个指数运算符(**). 2 ** 2 // 4 2 ** 3 // 8 这个运算符的一个特点是右结合,而不是常见的左结合. ...
- 【ES6】阮一峰ES6学习之迭代器和for...of循环
迭代器和for...of循环 1. 迭代器 1. 概念 2. 工作原理 3. 默认 Iterator 接口 4. 调用 Iterator 接口的场合 (1)解构赋值 (2) 扩展运算符 (3) yie ...
- js -- ES6(一)-- 简介(根据阮一峰ES6标准入门整理)
目前正在学习ES6,根据阮一峰的ES6入门2,学到哪更新到哪里,都是基本的知识,复杂的目前还不会,涉及的代码都是亲自运行过的,若发现错误请指正. ES6 提供了许多新特性,但是并不是所有的浏览器都能够 ...
- 阮一峰 / ES6 数组的解构赋值
目录 一.定义 二.详情讲解 1.数组解构:数组解构时数组的元素是按次序排列的,变量的取值由它的位置决定 2.对象解构:对象解构时对象的属性没有次序,变量必须与属性同名,才能取到正确的值. 三.用途 ...
- 实现阮一峰ES6的顶部加载条效果
效果例子 阮一峰的ES6:http://es6.ruanyifeng.com/?search=s&x=13&y=3 html + css <style type="te ...
- 《ES6》(阮一峰)学习笔记
一.简介 ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现 各大浏览器的最新版本,对 ES6 的支持可以查看kangax.github.io/compa ...
- 【ES6】阮一峰ES6学习之Class(一)
Class的基本用法 1. 类的由来 2. constructor() 方法 3. 类的实例 4. 取值函数(getter)和存值函数(setter) 5. 静态方法 6. 私有方法和私有属性 7. ...
最新文章
- 二叉树:root==NULL和*root==NULL的区别
- 有效用例模式阅读笔记三
- mysql的单行注释_MySQL基础--会这些就够了
- leetcode 564,546
- java中手动装入新类到类装饰器_关于java:抽象装饰器类中的功能而不是装饰器...
- mysql报错注入实战_手工注入——MySQL手工注入实战和分析
- 随想录(熟练掌握uml)
- 江浙沪地区计算机考研高效排名,京津冀,江浙沪地区院校盘点!
- Android--手势及触摸事件的注意点(一)
- 论文笔记_S2D.23_2011-ICCV_DTAM: 稠密的实时跟踪和建图
- mysql 线程内存 回收_【MySQL】InnoDB后台线程与内存缓存池
- python修改app定位_APP自动化中三大定位工具
- 推荐5款精挑细选的软件,大幅提升工作效率,用一次就会爱上
- 傻傻弄不清楚SAP和ERP?
- 服务器虚拟化专用ovf模板,科学网—开放虚拟化格式规范2.0.0——OVF package - 唐宏伟的博文...
- C51 (矩阵键盘密码锁)
- BPM流程建模开发详解
- win7如何在桌面上加计算机,详细教您win7如何添加显示桌面图标
- k8s控制器——Replicaset和Deployment
- 通达信指标公式编写常用函数(三)——HHVBARS、LLVBARS