ECMAScript 6:五、Reflect

本文详细介绍了ECMAScript6中的Reflect对象,包括其设计目的、与Object对象的区别、静态方法(如get、set、has、deleteProperty等)以及如何配合Proxy实现观察者模式。通过实例展示了Reflect对象在操作对象属性和事件监听中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ECMAScript 6:五、Reflect

1 前言

ES6学习笔记5:Reflect。

学习地址:

https://es6.ruanyifeng.com/#docs/reflect

2 笔记

(1)概述

Reflect对象与Proxy对象一样,也是 ES6 为了操作对象而提供的新 API。Reflect对象的设计目的有这样几个。Reflect理解为Javascript的反射操作API,Java等语言均有反射API供获取字段Field、Method、Constructor并调用等等

(1) 将Object对象的一些明显属于语言内部的方法(比如Object.defineProperty),放到Reflect对象上。现阶段,某些方法同时在Object和Reflect对象上部署,未来的新方法将只部署在Reflect对象上。也就是说,从Reflect对象上可以拿到语言内部的方法。

(2) 修改某些Object方法的返回结果,让其变得更合理。比如,Object.defineProperty(obj, name, desc)在无法定义属性时,会抛出一个错误,而Reflect.defineProperty(obj, name, desc)则会返回false。

// 老写法
try {
   
  Object.defineProperty(target, property, attributes);
  // success
} catch (e) {
   
  // failure
}

// 新写法
if (Reflect.defineProperty(target, property, attributes)) {
   
  // success
} else {
   
  // failure
}

(3) 让Object操作都变成函数行为。某些Object操作是命令式,比如name in obj和delete obj[name],而Reflect.has(obj, name)和Reflect.deleteProperty(obj, name)让它们变成了函数行为。

// 老写法
'assign' in Object // true

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

(4)Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法。这就让Proxy对象可以方便地调用对应的Reflect方法,完成默认行为,作为修改行为的基础。也就是说,不管Proxy怎么修改默认行为,你总可以在Reflect上获取默认行为。

Proxy(target, {
   
  set: function(target, name, value, receiver) {
   
    var success = Reflect.set(target, name, 
    value, receiver);
    if (success) {
   
      console.log('property ' 
      + name + ' on ' + target + ' set to ' + value);
    }
    return success;
  }
});

上面代码中,Proxy方法拦截target对象的属性赋值行为。它采用Reflect.set方法将值赋值给对象的属性,确保完成原有的行为,然后再部署额外的功能。

下面是另一个例子。

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);
  }
});

上面代码中,每一个Proxy对象的拦截操作(get、delete、has),内部都调用对应的Reflect方法,保证原生行为能够正常执行。添加的工作,就是将每一个操作输出一行日志。

有了Reflect对象以后,很多操作会更易读。

const {
   log:l} = console;

// 老写法
l(Function.prototype.apply.call(Math.floor, undefined, [1.75])) // 1

// 新写法
l(Reflect.apply(Math.floor, undefined, [1.75])) // 1

(2)静态方法

Reflect对象一共有 13 个静态方法。

Reflect.apply(target, thisArg, args)
Reflect.construct(target, args)
Reflect.get(target, name, receiver)
Reflect.set(target, name, value, receiver)
Reflect.defineProperty(target, name, desc)
Reflect.deleteProperty(target, name)
Reflect.has(target, name)
Reflect.ownKeys(target)
Reflect.isExtensible(target)
Reflect.preventExtensions(target)
Reflect.getOwnPropertyDescriptor(target, name)
Reflect.getPrototypeOf(target)
Reflect.setPrototypeOf(target, prototype)

上面这些方法的作用,大部分与Object对象的同名方法的作用都是相同的,而且它与Proxy对象的方法是一一对应的。下面是对它们的解释。


Reflect.get(target, name, receiver)

Reflect.get方法查找并返回target对象的name属性,如果没有该属性,则返回undefined。

var myObject = {
   
    num: 1,
    age: 2,
    get sumPrint() {
   
        return this.num + this.age;
    },
}

l(Reflect.get(myObject, 'num')) // 1
l(Reflect.get(myObject, 'age')) // 2
l(Reflect.get(myObject, 'sumPrint')) // 3
l(Reflect.get(myObject, 'print')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值