ES6——Reflect


之前的文章:

  1. ES6——Symbol
  2. ES6——Proxy

概述

Reflect 对象与Proxy 对象一样,也是 ES6 为了操作对象而提供的新 API.

切记,不可使用new操作符生成实例

特点

  1. 现阶段,Object上面内部语言方法(例 Object.defineProperty)会同步到Reflect上面一份。后续新增的则会放在Reflect对象上面。
  2. 修改某些Object的内部方法返回结果,使其变的合理。(以Object.defineProperty为例, 现在如果没有办法定义时,则会报错,放在Reflect上面,则会返回false)
  3. 使得Object的行为都变成函数形式(现如今,对于对象的操作,基本都是一行代码,对于解读,有点难。例如: delete obj.name .这种语句很容易让人忽略,并且如果没有注释,让人摸不住头脑)
  4. 配合Proxy,静态方法基本和Proxy的静态方法保持一致。

代码例子:(注意看注释)

// 1. new 操作符会报错,因为Reflect里面没有对应的构造函数
let reflect = new Reflect() // TypeError: Reflect is not a constructor
// 2. 对比方法,以Object.defineProperty为例。第一个结果是报错,第二个例子是false。
// 无法使用Object.defineProperty进行定义的属性有以下特点:
	// 1. 内置对象的不可配置属性(例如:下例)
	// 2. 特殊属性(例如:__proto__)
	// 3. 全局对象的属性
	// 4. 无法定义不可枚举的原型属性
	// 5. 不可写和不可配置的属性等
try {  
  Object.defineProperty(Math, 'PI', {  
    value: 3, // 尝试将PI的值修改为3  
    writable: true,  
    enumerable: true,  
    configurable: true  
  });  
} catch (e) {  
  console.error('Error:', e); // TypeError: Attempted to redefine non-configurable property 'PI'  
}
try {  
  Reflect.defineProperty(Math, 'PI', {  
    value: 3, // 尝试将PI的值修改为3  
    writable: true,  
    enumerable: true,  
    configurable: true  
  });  
} catch (e) {  
  console.error('Error:', e); 
}
// 3. Object 的操作变成函数操作
let obj = {a: 1}
'a' in obj
Reflect.has(obj, 'a')
// 配合Proxy 进行使用
// 每一个 Proxy 对象的拦截操作( get 、 delete 、 has ),内部都调用对应的 Reflect 方法,保证原生行为能够正常执行
var loggedObj = 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);
  }
});

静态方法

静态方法名称

  1. Reflect.apply(target, thisArg, args)
  2. Reflect.construct(target, args)
  3. Reflect.get(target, name, receiver)
  4. Reflect.set(target, name, value, receiver)
  5. Reflect.defineProperty(target, name, desc)
  6. Reflect.deleteProperty(target, name)
  7. Reflect.has(target, name)
  8. Reflect.ownKeys(target)
  9. Reflect.isExtensible(target)
  10. Reflect.preventExtensions(target)
  11. Reflect.getOwnPropertyDescriptor(target, name)
  12. Reflect.getPrototypeOf(target)
  13. Reflect.setPrototypeOf(target, prototype)

部分静态方法例子

Reflect.get(target, name, receiver)

  1. Reflect.get方法查找并返回 target 对象的 name 属性值,如果没有该属性,则返回 undefined 。
  2. 如果 name 属性部署了读取函数(getter),则读取函数的 this 绑定 receiver 。
  3. 如果第一个参数不是对象, Reflect.get 方法会报错。
// 说明1的例子如下: 
var myObject = {
  foo: 1,
  bar: 2,
  get baz() {
    return this.foo + this.bar;
  },
}
console.log(Reflect.get(myObject, 'foo')) // 1 
console.log(Reflect.get(myObject, 'bar')) // 2
console.log(Reflect.get(myObject, 'baz')) // 3 没有传receiver,则this取原对象
console.log(Reflect.get(myObject, 'zzz')) // undefined
// 说明2的例子如下: 
const otherObject = {
	foo: 3,
	bar: 4
}
console.log(Reflect.get(myObject, 'baz', otherObject)) // 7
// 说明3的例子如下: 
console.log(Reflect.get(1, 'baz'))  // TypeError: Reflect.get called on non-object

Reflect.has(target, name)

  1. Reflect.has方法对应name in obj里面的in运算符。
  2. 如果 Reflect.has() 方法的第一个参数不是对象,会报错。
// 说明1的例子如下: 
var myObject = {
  foo: 1,
}
console.log(Reflect.has(myObject, 'foo')) // true
console.log(Reflect.has(myObject, 'zzz')) // false
// 说明2的例子如下: 
console.log(Reflect.has(1, 'baz'))  // TypeError: Reflect.has called on non-object

Reflect.deleteProperty(target, name)

  1. Reflect.deleteProperty方法等同于delete obj[name],用于删除对象的属性。
  2. 注意:**如果删除成功,或者被删除的属性不存在,返回 true ;删除失败,被删除的属性依然存在,返回 false **
  3. 如果 Reflect.deleteProperty() 方法的第一个参数不是对象,会报错。
// 说明1,2的例子如下: 
var myObject = {
  foo: 1,
}
console.log(Reflect.deleteProperty(myObject, 'foo')) // true
console.log(Reflect.deleteProperty(myObject, 'zzz')) // true
// 此时的myObject 就是{}

Reflect.construct(target, args)

  1. Reflect.construct 方法等同于 new target(…args),这提供了一种不使用 new ,来调用构造函数的方法。
  2. 如果 Reflect.construct () 方法的第一个参数不是对象,会报错。
// 说明1的例子如下: 
function Greeting(name) {
  this.name = name;
}
// new 的写法
const instance = new Greeting('张三');
// Reflect.construct 的写法
const instance1 = Reflect.construct(Greeting, ['张三']); // {name: '张三'}
// 说明2的例子如下: 
console.log(Reflect.construct(1, 'baz'))  // TypeError: Reflect.construct called on non-object

实现观察者模式

// 这里就是简单观察者的核心逻辑,主要实现两个功能,一个就是observe,另一个就是observable
// 先定义了一个Set 集合,所有观察者函数都放进这个集合。
// observable 函数返回一个原始对象的 Proxy 代理,拦截赋值操作,触发充当观察者的各个函数
// 拦截函数 set 之中,会自动执行所有观察者
const queuedObservers = new Set();
const observe = fn => queuedObservers.add(fn);
const observable = obj => new Proxy(obj, {set});
function set(target, key, value, receiver) {
  const result = Reflect.set(target, key, value, receiver);
  queuedObservers.forEach(observer => observer());
  return result;
}
// 使用如下:
const person = observable({
  name: '张三',
  age: 20
});
function print() {
  console.log( ${person.name}, ${person.age} )
}
observe(print);
person.name = '李四';
  • 22
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值