从零开始学_JavaScript_系列(47)——Reflect
来源:互联网 发布:oracle数据库log文件 编辑:程序博客网 时间:2024/05/16 19:20
Reflect
1、是什么?
- window的原生对象,但不能通过new来生成实例;
- 对对象的属性的操作,都可以通过这个来完成(读、写、定义属性等);
- 返回值更加合理(失败返回false而不是抛错);
- 函数式调用(而非属性式)
- 在使用Proxy时,使用本方法效果比直接通过对象属性调用效果更好
2、如何使用(几种常见方法示例)
2.1、读
Reflect.get(target, propertyKey[, receiver])
拦截对target对象的propertyKey属性的读取,返回这个属性的值。
- 参数一是被访问的对象;
- 参数二是属性名;
- 参数三当遇见getter时,将getter的this指向他
参数一和参数二好理解,如代码:
let target = { _test: 1, get test() { return this._test; }};Reflect.get(target, "_test"); //1Reflect.get(target, "test"); //1
参数三比较特殊,当遇见getter时,getter的this将指向他。下面代码可以很好的体现这一点:
let receiver = {_test: 2}let target = { _test: 1, get test() { console.log(this === target, this === receiver); return this._test; }};Reflect.get(target, "test", receiver);// false true// 2target.test;// true false// 1
通过Reflect.get调用时(且有第三个参数),this指向参数三;
当通过target.test调用时,this指向对象本身;
2.2、写
Reflect.set(target, propertyKey, value[, receiver])
如果理解Reflect.get
了,那么理解Reflect.set
自然也很简单了。
- 参数一是目标对象;
- 参数二是属性名;
- 参数三是要设置的值;
- 参数四是遇见setter时,this指向的目标;
- 返回值是是否设置成功,成功则为true,报错为false;
如代码:
let receiver = {_test: 2};let target = { _test: 1, get test() { return this._test; }, set test(val) { this._test = val; }};Reflect.set(target, "test", "a"); //truetarget.test; //"a"//修改setter的this指向目标Reflect.set(target, "test", "b", receiver); //truetarget.test; //"a"receiver._test; //"b"//修改被禁止修改的属性Object.defineProperty(target, "test", { value: 1});Reflect.set(target, "test", "a"); //falsetarget.test; //1
3、观察者模式
观察者模式是结合了Proxy代理以及Reflect实现的,重点是Proxy。
我这里对阮一峰给的示例代码略有修改,并添加注释,以示使用方法:
//存储观察者函数,用数组也可以const queuedObservers = new Set();// const queuedObservers = [];//定义observe函数,执行本函数会将观察者函数添加到queuedObservers中,返回的是观察者函数的列表const observe = fn => queuedObservers.add(fn);// const observe = fn => queuedObservers.push(fn);//定义observable函数,将该对象添加代理后返回proxy实例const observable = obj => new Proxy(obj, {set});//handler,执行时会调用观察者里函数里的每个观察者function set(target, key, value, receiver) { const result = Reflect.set(target, key, value, receiver); queuedObservers.forEach(observer => observer(key, value)); return result;}//对对象进行代理绑定const person = observable({ name: '张三', age: 20});//定义2个函数function printKey(key, value) { console.log("key: " + key)}function printValue(key, value) { console.log("value: " + value)}//将函数设置为观察者函数observe(printKey);observe(printValue);//调用person(proxy实例)的属性nameperson.name = '李四';//输出//key: name//value: 李四//创建另外一个被观察的对象(空)const foo = observable({});//给他添加一个属性(触发set),因此会触发所有添加到观察者里的函数foo.fruit = "梨";//输出//key: fruit//value: 梨
简单来说:
- 可以创建一个函数用于进行proxy绑定(observable);
- 并且创建一个观察者列表,用于添加你的观察者函数(列表queuedObservers,添加函数observe);
- 因为是proxy,所以你还需要一个handler,并且假定你handler里的set会执行所有观察者函数;
- 然后所有被绑定过的函数,在使用它的返回值时(即proxy实例),你设置对象属性就会触发handler的set,而set就会执行所有观察者函数;
- 于是有了上面示例代码发生的情况;
阅读全文
0 0
- 从零开始学_JavaScript_系列(47)——Reflect
- 从零开始学_JavaScript_系列(30)——NodeList
- 从零开始学_JavaScript_系列(32)——事件广播
- 从零开始学_JavaScript_系列(43)——Symbol简述
- 从零开始学_JavaScript_系列(58)——Thunk函数
- 从零开始学_JavaScript_系列(59)——async函数
- 从零开始学_JavaScript_系列(15)——js系列<3>(转为字符串,截取字符串)
- 从零开始学_JavaScript_系列(16)——js系列<5>(正则表达式)
- 从零开始学_JavaScript_系列(19)——js系列<6>闭包
- 从零开始学_JavaScript_系列(三)——CSS相关(基础、选择器、position、div)
- 从零开始学_JavaScript_系列(14)——dojo(7)(饼图,BorderContainer,hashchange,弹窗)
- 从零开始学_JavaScript_系列(17)——dojo(6)(声明一个类declare)
- 从零开始学_JavaScript_系列(18)——dojo(7)(dojo中类的继承)
- 从零开始学_JavaScript_系列(46)——Proxy代理(给对象加壳)
- 从零开始学_JavaScript_系列(23)——css<5>滚动条,Tab,spellcheck,img放置
- 从零开始学_JavaScript_系列(24)——查看对象属性,合并数组
- 从零开始学_JavaScript_系列(25)——dojo(10)摧毁一个widget
- 从零开始学_JavaScript_系列(26)——只需要前端知识的ajax教程
- 炮兵阵地 POJ
- 实验五:JPEG解码
- Leetcode183. Customers Who Never Order
- React PropTypes 定义组件的属性类型和默认属性
- call和apply的区别
- 从零开始学_JavaScript_系列(47)——Reflect
- 重新开始的勇气
- 基础数据结构03:栈
- mysql表属性修改
- Hie with the Pie POJ
- 建造型——抽象工厂模式
- 【Docker容器的数据管理】- 数据卷的使用
- MyEclipse8.6破解方法
- Travelling HDU