导航
导航
文章目录󰁋
  1. 一、简介
    1. 1.1 什么是Reflect
    2. 1.2 为什么要设计Reflect
  2. 二、Reflect的API
    1. 2.1 Reflect.get(target,property,receiver)
    2. 2.2 Reflect.set(target,propName,propValue,receiver)
    3. 2.3 Reflect.set与Proxy.set
    4. 2.4 Reflect.has(obj,name)
    5. 2.5 Reflect.deleteProperty(obj, name)
    6. 2.6 Reflect.construct(target, args)
    7. 2.7 Reflect.getPrototypeOf(obj)
    8. 2.8 Reflect.setPrototypeOf(obj, newProto)
    9. 2.9 Reflect.apply(func, thisArg, args)
    10. 2.10 Reflect.defineProperty(target, propertyKey, attributes)
    11. 2.11 Reflect.getOwnPropertyDescriptor(target, propertyKey)
    12. 2.12 Reflect.isExtensible (target)
    13. 2.13 Reflect.preventExtensions(target)
    14. 2.14 Reflect.ownKeys (target)

ES6系列之Reflect

一、简介

1.1 什么是Reflect

为操作对象而提供的新API

1.2 为什么要设计Reflect

  1. Object对象的属于语言内部的方法放到Reflect对象上,即从Reflect对象上拿Object对象内部方法
  2. 将用老Object方法报错的情况,改为返回false
1
2
3
4
5
6
7
// 旧写法
try {
Object.defineProperty(target, property, attributes);
// success
} catch (e) {
// failure
}
1
2
3
4
5
6
// 新写法
if (Reflect.defineProperty(target, property, attributes)) {
// success
} else {
// failure
}
  1. Object操作变成函数行为
1
2
// 旧写法
'name' in Object //true
1
2
// 新写法
Reflect.has(Object,'name') //true
  1. ReflectProxy是相辅相成的,在Proxy上有的方法,在Reflect就一定有
1
2
3
4
5
6
7
8
9
10
11
12
let target={}
let handler={
set(target,proName,proValue,receiver){
//确认对象的属性赋值成功
let isSuccess=Reflect.set(target,proName,proValue,receiver)
if(isSuccess){
console.log("成功")
}
return isSuccess
}
}
let proxy=new Proxy(target,handler)

确保对象的属性能正确赋值,广义上讲,即确保对象的原生行为能够正常进行,这就是Reflect的作用

二、Reflect的API

注:和ProxyAPI一致

2.1 Reflect.get(target,property,receiver)

查找并返回target对象的property属性

1
2
3
4
5
let obj={
name:"poetries",
}
let result=Reflect.get(obj,"name")
console.log(result) //poetries
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let obj={
//属性yu部署了getter读取函数
get yu(){
//this返回的是Reflect.get的receiver参数对象
return this.name+this.age
}
}

let receiver={
name:"shen",
age:"18",
}

let result=Reflect.get(obj,"yu",receiver)
console.log(result) //shen18

注意:如果Reflect.get()的第一个参数不是对象,则会报错

2.2 Reflect.set(target,propName,propValue,receiver)

设置target对象的propName属性为propValue

1
2
3
4
5
6
7
let obj={
name:"poetries"
}

let result=Reflect.set(obj,"name","静观流叶")
console.log(result) //true
console.log(obj.name) //静观流叶

2.3 Reflect.set与Proxy.set

Reflect.setProxy.set联合使用,并且传入receiver,则会进行定义属性操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
let obj={
name:"chen"
}

let handler={
set(target,key,value,receiver){
console.log("Proxy拦截赋值操作")
//Reflect完成赋值操作
Reflect.set(target,key,value,receiver)
},
defineProperty(target,key,attribute){
console.log("Proxy拦截定义属性操作")
//Reflect完成定义属性操作
Reflect.defineProperty(target,key,attribute)
}
}

let proxy=new Proxy(obj,handler)
proxy.name="ya"
//Proxy拦截赋值操作
//Proxy拦截定义属性操作

为什么Reflect.set()传入receiver参数,就会触发定义属性的操作?

因为Proxy.set()中的receiverProxy的实例,即obj,而Reflect.set一旦传入receiver,就会将属性赋值到receiver上面,也是obj,所以就会触发defineProperty拦截

2.4 Reflect.has(obj,name)

1
2
3
var obj= {
name: "poetries",
};
1
2
//旧写法
'name' in obj // true
1
2
//新写法
Reflect.has(obj, 'name') // true

2.5 Reflect.deleteProperty(obj, name)

删除对象的属性

1
2
// 旧写法
delete obj.name;
1
2
// 新写法
Reflect.deleteProperty(obj, 'name');

2.6 Reflect.construct(target, args)

1
2
3
function Person(name) {
this.name = name;
}
1
2
// 旧 new写法
let person= new Person('poetries')
1
2
// 新写法:Reflect.construct 的写法
let person = Reflect.construct(Person, ['poetries']);

2.7 Reflect.getPrototypeOf(obj)

用于读取对象的proto属性,对应Object.getPrototypeOf(obj)

2.8 Reflect.setPrototypeOf(obj, newProto)

设置目标对象的原型(prototype),对应Object.setPrototypeOf(obj, newProto)方法

2.9 Reflect.apply(func, thisArg, args)

继承目标对象的特定方法

1
let array=[1,2,3,4,5,6]
1
2
3
4
// 旧写法
let small= Math.min.apply(Math, array) //1
let big = Math.max.apply(Math, array) //6
let type = Object.prototype.toString.call(small) //"[object Number]"
1
2
3
4
5
// 新写法
const small= Reflect.apply(Math.min, Math, array)
const big = Reflect.apply(Math.max, Math, array)
//第三个参数是Object类型的就好,因为调用的是Object的原型方法toString
const type = Reflect.apply(Object.prototype.toString, small, [])

2.10 Reflect.defineProperty(target, propertyKey, attributes)

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

Proxy.defineProperty配合使用

1
2
3
4
5
6
7
8
9
10
let proxy = new Proxy({}, {
defineProperty(target, prop, descriptor) {
console.log(descriptor);
return Reflect.defineProperty(target, prop, descriptor);
}
});

proxy .name= 'chen';
// {value: "chen", writable: true, enumerable: true, configurable: true}
p.name // "chen"

如上,Proxy.defineProperty对属性赋值设置拦截,然后使用Reflect.defineProperty完成赋值

2.11 Reflect.getOwnPropertyDescriptor(target, propertyKey)

基本等同于Object.getOwnPropertyDescriptor,用于得到指定属性的描述对象

2.12 Reflect.isExtensible (target)

对应Object.isExtensible,返回一个布尔值,表示当前对象是否可扩展

2.13 Reflect.preventExtensions(target)

对应Object.preventExtensions方法,用于让一个对象变为不可扩展。它返回一个布尔值,表示是否操作成功

2.14 Reflect.ownKeys (target)

用于返回对象的所有属性

支持一下
扫一扫,支持poetries
  • 微信扫一扫
  • 支付宝扫一扫