“睡服”面试官系列第十七篇之Reflect(建议收藏学习)

本文详细介绍了JavaScript的Reflect API,包括Reflect.get、Reflect.set、Reflect.has等13个静态方法,阐述了它们与Object方法的区别及作用,并通过实例展示了如何使用Proxy配合Reflect实现观察者模式,帮助读者更好地理解和运用Reflect对象。

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

目录

 

1. 概述

2. 静态方法

2.1Reflect.get(target, name, receiver)

2.2Reflect.set(target, name, value, receiver)

2.3Reflect.has(obj, name)

2.4Reflect.deleteProperty(obj, name)

2.5Reflect.construct(target, args)

2.6Reflect.getPrototypeOf(obj)

2.7Reflect.setPrototypeOf(obj, newProto)

2.8Reflect.apply(func, thisArg, args)

2.9Reflect.defineProperty(target, propertyKey, attributes)

2.10Reflect.getOwnPropertyDescriptor(target, propertyKey)

2.11Reflect.isExtensible (target)

 2.12Reflect.preventExtensions(target)

2.13Reflect.ownKeys (target)

3. 实例:使用 Proxy 实现观察者模式


1. 概述

Reflect 对象与 Proxy 对象一样,也是 ES6 为了操作对象而提供的新 API。 Reflect 对象的设计目的有这样几个。
(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) {
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 对象以后,很多操作会更易读。

// 老写法
Function.prototype.apply.call(Math.floor, undefined, [1.75]) // 1
// 新写法
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 对象的方法是一一对应的。下面是对它们的解释。

2.1Reflect.get(target, name, receiver)

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

var myObject = {
foo: 1,
bar: 2,
get baz() {
return this.foo + this.bar;
},
}
Reflect.get(myObject, 'foo') // 1
Reflect.get(myObject, 'bar') // 2
Reflect.get(myObject, 'baz') // 3
评论 33
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端小歌谣

放弃很容易 但是坚持一定很酷

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值