Reflect
Reflect可以用于获取目标对象的行为,它和Objec类似,但是更加易读,给开发者提供了一种更加优雅的方式。它的方法和Proxy是对应的。
1.代替Object的某些方法
2.修改某些Obje方法返回的结果
3.把命令式变为函数行为
4.配合Proxy!!!
一、代替Object的某些方法
let obj = {}
Reflect.defineProperty(obj,"name",{
value:"starry",
writable:false, //是否可以被修改
enumerable:false // 是否可以被枚举
})
console.log(obj)
这里对对象进行了一个简单映射,并且添加了一下属性
二、修改某些Obje方法返回的结果
let obj = {}
Object.defineProperty(obj,"name",{
value:"starry",
writable:true, //是否可以被修改
enumerable:true // 是否可以被枚举
})
let res = Object.defineProperty(obj,"name",{
value:"A",
})
console.log(res) //{name: 'A'} 修改成功,返回对象
这里是Object.defineProperty的方法,但是假如将writable:true改为false,就会报错。
let obj = {}
Object.defineProperty(obj, "name", {
value: "starry",
writable: false, // !!!改为false
enumerable: true
})
let res = Object.defineProperty(obj, "name", {
value: "A",
})
console.log(res)
所以在以前开发中,对于Object.defineProperty的使用一般会放置在try catch中,以防止程序突然中断。而Reflect则不会有这个问题。
let obj = {}
Reflect.defineProperty(obj, "name", {
value: "starry",
writable: false, //是否可以被修改
enumerable: false // 是否可以被枚举
})
let res = Reflect.defineProperty(obj, "name", {
value: "A",
})
console.log(res) // false 不被打断,返回 false
下面是实际开发过程中新老写法对比
//老写法
try {
Object.defineProperty(target, property, attributes)
// success
} catch (e) {
//fail
}
//新写法
if (Reflect.defineProperty(target, property, attributes)) {
// success
} else {
//fail
}
三、把命令式变为函数行为
JS中一些不规范的命令式写法一直是被吐槽的,而Reflect则可以实现函数式写法,更加的科学
let obj = {
name: "starry"
}
//老写法
console.log("name" in obj) // true
//新写法
console.log(Reflect.has(obj,"name")) // true
//老写法
console.log(delete obj.name) // true
//新写法
console.log(Reflect.deleteProperty(obj,"name")) // true
四、配合Proxy
先简单演示一些Reflect中的get和set,一个访问一个修改或者添加,看代码
let obj = {
name: "starry"
}
console.log( Reflect.get(obj,"name")) // starry
Reflect.set(obj,"age",18) // 添加
Reflect.set(obj,"name","W") //修改
console.log(obj) // {name: 'W', age: 18}
接下来就可以学习如何配合Proxy使用啦
let s = new Set()
let proxy = new Proxy(s, {
get(target, key) {
//老写法
// let res = target[key]
//新写法
let res = Reflect.get(target,key) // 看起来更麻烦,但是往下看Set
if (res instanceof Function) {
return res.bind(target)
}
return res
},
set(target,key,value) {
// Reflect.set(target,key,value) // 简答写法,把参数都给到set
Reflect.set(...arguments) //逼格拉满,直接把默认行为都给到了Proxy上,再也不用担心上面this指向问题了
}
})
上面是Proxy中的例子,主要为了对比,接下来我们结合Reflect把数组代理一下
let arr = []
let proxy = new Proxy(arr, {
get() {
return Reflect.get(...arguments)
},
set() {
return Reflect.set(...arguments)
}
})
简单几行代码,我们就成功代理了数组,不要担心方法的this指向,简直酷炫逆天,我们把参数打印一下来验证一下
let arr = []
let proxy = new Proxy(arr, {
get(target,key) {
console.log("get",key)
return Reflect.get(...arguments)
},
set(target,key,value) {
console.log("set",key,value)
return Reflect.set(...arguments)
}
})