es6利用Reflect实现观察者模式,并详解Reflect对象

字面意思:反映;映出(影像)

先看一个简易的观察者模式:

上述观察者模式代码运行后输出:

// 李四 20;
// 哈哈 10;

分析:
当const 声明person 对象后,该对象被observable初始化,同时该对象的写操作被Proxy所拦截, 调用observe(print)时,print方法被推入Set数据结构,作为缓存,执行person.name = ‘李四’,写操作被激活,调用Set结构中的缓存函数,执行 console.log(${target.name}, ${target.age})

当然上面的观察者模式并未对入参进行校验,添加错误检测。但已经足够说明Reflect带来的改变

Reflect是 ES6 为了操作对象而提供的新 API,目的是让对象的操作更加优雅。
优雅的体现如下:

1、修改某些Object方法的返回结果,让其变得更合理

//在出现无法定义的对象时此表达式的返回值
Object.defineProperty(obj, name, desc) //  undefined
Reflect.defineProperty(obj, name, desc) // 则会返回false

上面的优点在于进行判断的时候新写法会直接返回布尔值

2、 让Object操作都变成函数行为

// 老写法
'assign' in Object // true
// 新写法
Reflect.has(Object, 'assign') // true

上面的写法的优点在于,新写法更符合语义。

3、Reflect对象的方法与Proxy对象的方法一一对应

var Obj = new Proxy(obj, {get(target, name) {console.log('get', target, name);return Reflect.get(target, name);},deleteProperty(target, name) {console.log('delete' + name);return Reflect.deleteProperty(target, name);},has(target, name) {console.log('has' + name);return Reflect.has(target, name);}
});

不管Proxy怎么修改默认行为,你总可以在Reflect上获取默认行为,这为代理操作简化了代码,降低了代码量,很多操作会更易读。

重点:
现阶段,某些方法同时在Object和Reflect对象上部署,未来的新方法将只部署在Reflect对象上。也就是说,从Reflect对象上可以拿到语言内部的方法

4、 静态方法

1、Reflect.get(target, name, receiver)

Reflect.get方法查找目标对象上的name属性,如果找不到则返回undefined。

var myObject = {foo: 1,bar: 2,get baz() {return this.foo + this.bar;},
};
var myReceiverObject = {foo: 4,bar: 4,
};
Reflect.get(myObject, 'baz', myReceiverObject) // 8

由上可以看出:当Reflect.get参数传入 receiver参数时,name中的读操作的this会指向receiver内部;

2、Reflect.set(target, name, value, receiver)

Reflect.set方法设置target对象的name属性等于value

var myObject = {foo: 4,set bar(value) {return this.foo = value;},
};var myReceiverObject = {foo: 0,
};Reflect.set(myObject, 'bar', 1, myReceiverObject);
myObject.foo // 4
myReceiverObject.foo // 1

由上可以看出:当Reflect.set参数传入 receiver参数时,name中的写操作的this会指向receiver内部;

3、Reflect.has(obj, name)

var myObject = {foo: 1,
};// 旧写法
'foo' in myObject // true// 新写法
Reflect.has(myObject, 'foo') // true

has方法用来检测对象内部是否含有name属性

4、Reflect.deleteProperty(obj, name)

const myObj = { foo: 'bar' };
// 旧写法
delete myObj.foo;
// 新写法
Reflect.deleteProperty(myObj, 'foo');

Reflect.deleteProperty用来删除对象的name属性

5、Reflect.construct(target, args)

function Greeting(name) {this.name = name;
}
// new 的写法
const instance = new Greeting('张三');
// Reflect.construct 的写法
const instance = Reflect.construct(Greeting, ['张三']);

Reflect.construct提供了一种不使用new,来调用构造函数的方法。

5、Reflect.getPrototypeOf(obj)

const myObj = new FancyThing();
// 旧写法
Object.getPrototypeOf(myObj) === FancyThing.prototype;
// 新写法
Reflect.getPrototypeOf(myObj) === FancyThing.prototype;

Reflect.getPrototypeOf()用来查找目标的原型

6、Reflect.setPrototypeOf(obj, newProto)

const myObj = {};
// 旧写法
Object.setPrototypeOf(myObj, Array.prototype);
// 新写法
Reflect.setPrototypeOf(myObj, Array.prototype);
myObj.length // 0

Reflect.setPrototypeOf方法用于设置目标对象的原型(prototype)。

7、Reflect.apply(func, thisArg, args)

const ages = [11, 33, 12, 54, 18, 96];
// 旧写法
const youngest = Math.min.apply(Math, ages);
const oldest = Math.max.apply(Math, ages);
const type = Object.prototype.toString.call(youngest);
// 新写法
const youngest = Reflect.apply(Math.min, Math, ages);
const oldest = Reflect.apply(Math.max, Math, ages);
const type = Reflect.apply(Object.prototype.toString, youngest, []);

Reflect.apply用于绑定this对象后执行给定函数。

8、Reflect.defineProperty(target, propertyKey, attributes)

function MyDate() {/*…*/
}
// 旧写法
Object.defineProperty(MyDate, 'now', {value: () => Date.now()
});
// 新写法
Reflect.defineProperty(MyDate, 'now', {value: () => Date.now()
});

Reflect.defineProperty方法用来为对象定义属性。

9、Reflect.getOwnPropertyDescriptor(target, propertyKey)

var myObject = {};
Object.defineProperty(myObject, 'hidden', {value: true,enumerable: false,
});
// 旧写法
var theDescriptor = Object.getOwnPropertyDescriptor(myObject, 'hidden');
// 新写法
var theDescriptor = Reflect.getOwnPropertyDescriptor(myObject, 'hidden');

Reflect.getOwnPropertyDescriptor用于得到指定属性的描述对象

10、Reflect.isExtensible (target)

const myObject = {};
// 旧写法
Object.isExtensible(myObject) // true
// 新写法
Reflect.isExtensible(myObject) // true

Reflect.isExtensible表示当前对象是否可扩展。

11、Reflect.preventExtensions(target)

var myObject = {};// 旧写法
Object.preventExtensions(myObject) // Object {}// 新写法
Reflect.preventExtensions(myObject) // true

Reflect.preventExtensions用于让一个对象变为不可扩展;不可扩展意味着你不能在对象中添加属性

12、Reflect.ownKeys (target)

var myObject = {foo: 1,bar: 2,[Symbol.for('baz')]: 3,[Symbol.for('bing')]: 4,
};
// 旧写法
Object.getOwnPropertyNames(myObject)
// ['foo', 'bar']
Object.getOwnPropertySymbols(myObject)
//[Symbol(baz), Symbol(bing)]
// 新写法
Reflect.ownKeys(myObject)
// ['foo', 'bar', Symbol(baz), Symbol(bing)]

Reflect.ownKeys方法用于返回对象的所有属性

Reflect会逐步代替object对象的绝大部分功能,未来也有可能会完全取代object。Reflect-yyds

es6利用Reflect实现观察者模式,并详解Reflect对象相关推荐

  1. PHP观察者通知机制,观察者模式-通知详解

    观察者模式也叫发布/订阅模式,是软件设计模式中的一种.在这种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知.这通常透过呼叫各观察者所提供的方法来实现.此种模式通 ...

  2. ES6模块之export和import详解

    ES6模块之export和import详解 ES6中的模块即使一个包含JS代码的文件,在这个模块中所有的变量都是对其他模块不可见的,除非我们导出它.ES6的模块系统大致分为导出(export)和导入( ...

  3. Python算法教程第一章知识点:利用插入元素的例子详解list之本质

    声明:由于中译本翻译过于冗余,所以将有用处的知识点罗列出来. 微信公众号:geekkr 本文目录:一.利用插入元素的例子详解list之本质 </br> 一.利用插入元素的例子详解list之 ...

  4. python能处理nc文件吗_利用python如何处理nc数据详解

    前言 这两天帮一个朋友处理了些 nc 数据,本以为很简单的事情,没想到里面涉及到了很多的细节和坑,无论是"知难行易"还是"知易行难"都不能充分的说明问题,还是& ...

  5. altium designer利用向导画封装库详解

    altium designer利用向导画封装库详解 由于前人已经将方法总结得很好.在此引用前人的成果,以防时间一长就忘掉了.首先对前辈的工作表示感谢. altium designer6.9为例画一个B ...

  6. python处理nc数据_利用python如何处理nc数据详解

    利用python如何处理nc数据详解 来源:中文源码网    浏览: 次    日期:2018年9月2日 [下载文档:  利用python如何处理nc数据详解.txt ] (友情提示:右键点上行txt ...

  7. java控制excel_利用Java控制EXCEL实例详解

    利用Java控制EXCEL实例详解发布者:本站     时间:2020-05-06 15:05:43 使用Windows操作系统的朋友对Excel(电子表格)一定不会陌生,但是要使用Java语言来操纵 ...

  8. php开发面试题---php面向对象详解(对象的主要三个特性)

    php开发面试题---php面向对象详解(对象的主要三个特性) 一.总结 一句话总结: 对象的行为:可以对 对象施加那些操作,开灯,关灯就是行为. 对象的形态:当施加那些方法是对象如何响应,颜色,尺寸 ...

  9. 详解jQuery对象与DOM对象的相互转换

    一直以来对于通过jQuery方式获取的对象,却不能直接使用JavaScript的方法很不理解,现在知道,原来jQuery获得的对象并不和我们平时使用getElementById获得的对象一样.所以一些 ...

最新文章

  1. 只有程序员才懂的手势 | 每日趣闻
  2. 设计模式(第十七式:迭代器模式)
  3. python快递代取系统_代取快递的变现方式,校园跑腿的经营范围有多大?
  4. python 当日日期_Python程序寻找当日赢家
  5. LBS移动网络基站定位
  6. 『转』Dr.Web Security Space 8 – 免费3个月
  7. iOS 上的相机捕捉 swift
  8. 微信订阅号改回列表显示
  9. 人工智能语音如何实现?
  10. 计算机英语CMYK全称,CMYK是什么意思 CMYK与RGB的区别介绍
  11. 在esp32开发板上实现的web_radio,基于wm8978 codec芯片
  12. PHP地图规划骑行路径,高德路径规划,自定义骑行路线(适用3D地图)
  13. 公司员工后台管理系统界面设计-Axure9原型设计
  14. Flexbox 基础知识
  15. 服务器认证信息,认证信息管理系统、服务器、方法和程序
  16. 100层楼2个鸡蛋,测试其最低破碎楼层问题
  17. C6455CSL芯片支持库:第二节 EMAC外设
  18. STM32实现PT100测温系统设计报告(OLED屏显示)
  19. 图片马赛克处理以及上传保存—网页端
  20. 基于chatgpt开发QQ机器人

热门文章

  1. 互相关函数以及Matlab仿真
  2. 2021春招已正式开启,阿里巴巴企业智能事业部内推,有意者看下文!
  3. Kafka rebalance触发条件
  4. nginx的作用及原理(一)
  5. oracle篮球,篮球小王子!任嘉伦打篮球也不来赖,超爱11号
  6. 定义采购申请凭证类型
  7. 如果人工智能迎来下一个寒冬,你认为会是卡在什么问题上?
  8. 我的第一个Android应用软件——《飞鸟集》
  9. 超好用的清理软件Wise Disk Cleaner X
  10. API 开放接口设计之 appId,appSecret,accessToken (同微信开发平台接口)