Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
ES系列文章
Reflect和proxy的作用类似,也是代理拦截,但是Reflect主要面对的是内部语言的操作
- 将Object对象属于语言内部的方法(比如Object.defineProperty)放到Reflect对象上。
//Object -> Reflect
let obj = {}
let newVal = ''
Reflect.defineProperty(obj, 'name', {
get() {
return newVal
},
set(val) {
console.log('set')
// this.name = val
newVal = val
}
})
obj.name = 'es'
console.log(obj.name)
- 修改一些Object方法返回的结果,变得更合理。Object.defineProperty(obj, name, desc)在无法定义属性时,会抛出错误,而Reflect.defineProperty(obj, name, desc)则会返回布尔值。
try {
Object.defineProperty()
} catch (e) {}
if (Reflect.defineProperty()) { // boolean
} else {
}
- 让Object操作都变成函数行为。某些Object操作是命令式。
console.log('assign' in Object) // true
console.log(Reflect.has(Object, 'assign'))// true
- Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法。这就让Proxy对象可以方便地调用对应的Reflect方法,完成默认行为。也就是说,不管Proxy怎么修改默认行为,都可以在Reflect上获取默认行为
let user = {
name: 'xxx',
age: 18,
_password: '***'
}
user = new Proxy(user, {
get(target, prop) {
if (prop.startsWith('_')) {
throw new Error('不可访问')
} else {
// return target[prop]
return Reflect.get(target, prop)
}
},
set(target, prop, val) {
if (prop.startsWith('_')) {
throw new Error('不可访问')
} else {
// target[prop] = val
Reflect.set(target, prop, val)
return true
}
},
deleteProperty(target, prop) { // 拦截删除
if (prop.startsWith('_')) {
throw new Error('不可删除')
} else {
// delete target[prop]
Reflect.deleteProperty(target, prop)
return true
}
},
ownKeys(target) {
// return Object.keys(target).filter(key => !key.startsWith('_'))
return Reflect.ownKeys(target).filter(key => !key.startsWith('_'))
}
})
console.log(user.age)
try {
console.log(user._password)
} catch (e) {
console.log(e.message)
}
user.age = 18
console.log(user.age)
try {
user._password = 'xxx'
} catch (e) {
console.log(e.message)
}
// delete user.age
// console.log(user.age)
for (let key in user) {
console.log(key)
}
// apply
let sum = (...args) => {
let num = 0
args.forEach(item => {
num += item
})
return num
}
sum = new Proxy(sum, {
apply(target, ctx, args) {
// return target(...args) * 2
return Reflect.apply(target, target, [...args]) * 2
}
})
console.log(sum(1, 2))
console.log(sum.call(null, 1, 2, 3))
console.log(sum.apply(null, [1, 2, 3]))
一个前端小白,若文章有错误内容,欢迎大佬指点讨论!