function fn(x, y) {return x + y}const fnProxy = new Proxy(fn, {/*target: 目标函数(fn)thisArg: 指定的this对象 , 也就是被调用时的上下文对象({ name: 'curry' })argumentsList: 被调用时传递的参数列表([1, 2])*/apply: function(target, thisArg, argumentsList) {console.log('fn函数使用apply进行了调用')return target.apply(thisArg, argumentsList)},/*target: 目标函数(fn)argumentsList: 被调用时传递的参数列表newTarget: 最初被调用的构造函数(fnProxy)*/construct: function(target, argumentsList, newTarget) {console.log('fn函数使用new进行了调用')return new target(...argumentsList)}})fnProxy.apply({ name: 'curry' }, [1, 2]) // fn函数使用apply进行了调用new fnProxy() // fn函数使用new进行了调用
2.4.Proxy所有的捕获器除了上面提到的4种捕获器 , Proxy还给我们提供了其它9种捕获器 , 一共是13个捕获器 , 下面对这13个捕获器进行简单总结 , 下面表格的捕获器分别对应对象上的一些操作方法 。
捕获对象
get()
属性读取操作
set()
属性设置操作
has()
in操作符
deleteProperty()
delete操作符
apply()
函数调用操作
construct()
new操作符
getPrototypeOf()
Object.getPrototypeOf()
setPrototypeOf()
Object.setPrototypeOf()
isExtensible()
Object.isExtensible()
preventExtensions()
Object.perventExtensions()
getOwnPropertyDescriptor()
Object.getOwnPropertyDescriptor()
defineProperty()
Object.defineProperty()
ownKeys()
Object.getOwnPropertySymbols()
Proxy捕获器具体用法可查阅MDN:https://developer.mozilla.org/zh-CN/docs/Web/JAVAScript/Reference/Global_Objects/Proxy
3.Reflect
在ES6中 , 还新增了一个API为Reflect , 翻译为反射 , 为一个内置对象 , 一般用于搭配Proxy进行使用 。3.1.Reflect有什么作用呢?
可能会有人疑惑 , 为什么在这里提到Reflect , 它具体有什么作用呢?怎么搭配Proxy进行使用呢?
- Reflect上提供了很多操作JavaScript对象的方法 , 类似于Object上操作对象的方法;
- 比如:Reflect.getPrototypeOf()类似于Object.getPrototypeOf() , Reflect.defineProperty()类似于Object.defineProperty();
- 既然Object已经提供了这些方法 , 为什么还提出Reflect这个API呢?这里涉及到早期ECMA规范问题 , Object本是作为一个构造函数用于创建对象 , 然而却将这么多方法放到Object上 , 本就是不合适的;所以 , ES6为了让Object职责单一化 , 新增了Reflect , 将Object上这些操作对象的方法添加到Reflect上 , 且Reflect不能作为构造函数进行new调用;
在上述Proxy中 , 操作对象的方法都可以换成对应的Reflect上的方法 , 基本使用如下:
const obj = {name: 'curry',age: 30}// 创建obj的代理对象const objProxy = new Proxy(obj, {// 获取对象属性值的捕获器get: function(target, key) {console.log(`obj对象的${key}属性被访问啦!`)return Reflect.get(target, key)},// 设置对象属性值的捕获器set: function(target, key, newValue) {console.log(`obj对象的${key}属性被设置啦!`)Reflect.set(target, key, newValue)},// 删除对象属性的捕获器deleteProperty: function(target, key) {console.log(`obj对象的${key}属性被删除啦!`)Reflect.deleteProperty(target, key)}})// 设置:objProxy.name = 'kobe' // obj对象的name属性被设置啦!objProxy.age = 24 // obj对象的age属性被设置啦!// 访问:console.log(objProxy.name) // obj对象的name属性被访问啦!console.log(objProxy.age) // obj对象的age属性被访问啦!// 删除:delete objProxy.name // obj对象的name属性被删除啦!
3.3.Reflect上常见的方法对比Object , 我们来看一下Reflect上常见的操作对象的方法(静态方法):
类似于
get(target, propertyKey [, receiver])
获取对象某个属性值 , target[name]
set(target, propertyKey, value [, receiver])
将值分配给属性的函数 , 返回一个boolean
has(target, propertyKey)
判断一个对象是否存在某个属性 , 和in运算符功能相同
推荐阅读
- 您与这个网站的连接不安全?教你用python轻松解决
- 带状疱疹饮食注意什么
- 给你一个团队,你该怎么带?做好这五点,团队大变样!
- 春天到了,30种野菜辨别图片,带你认识不同的野菜和吃法
- 红烧带鱼烧豆腐的做法
- 吃野菜,带你进入健康地带
- 无神之界|我拼尽全力考上的二本,难道带给我的只能是耻辱吗?女研究生痛哭中发出灵魂之问
- 韩国|开放的“韩国”现状,带你看看真实的韩国
- 黄瓜|恩克减肥34天后回归,体重不降反增加,网友:安全带尽力了
- 大一新生入学必备清单 上大学要带什么东西