【ES6】Reflect反射机制


一、Reflect概述

Reflect 对象与 Proxy 对象一样,也是 ES6 为了操作对象而提供的新 API。 Reflect 对象的设计目的及特点:

  • 将 Object 对象的一些明显属于语言内部的方法(比如 Object.defineProperty ),放到 Reflect对象上。
    现阶段,某些方法同时在 Object 和Reflect 对象上部署,未来的新方法将只部署在Reflect 对象上。也就是说,从Reflect 对象上可以拿到语言内部的方法。
  • 修改某些 Object 方法的返回结果,让其变得更合理。
    比如,Object.defineProperty(obj, name, desc)在无法定义属性时,会抛出一个错误,而Reflect.defineProperty(obj, name, desc) 则会返回 false。
  • 让Object操作变成函数行为
    -某些 Object 操作是命令式,比如 name in obj 和 delete obj[name] ,而 Reflect.has(obj, name) 和Reflect.deleteProperty(obj, name) 让它们变成了函数行为。
  • Reflect对象的方法与Proxy对象的方法一一对象
    只要是 Proxy 对象的方法,就能在 Reflect 对象上找到对应的方法。这就让 Proxy 对象可以方便 地调用对应的 Reflect 方法,完成默认行为,作为修改行为的基础。也就是说,不管 Proxy 怎么修改默认行为,你总可以在 Reflect 上获取默认行为。

二、用法详解

1.Object -> Reflect

Object.defineProperty可用Reflect.defineProperty代替

let obj = {}
let newVal = ''
Reflect.defineProperty(obj, 'name', {
    get() {
        return newVal
    },
    set(val) {
        console.log('set') // set
        // this.name = val
        newVal = val
    }
})
obj.name = 'es'
console.log(obj.name) // es


2. 修改Object方法的返回结果

// ES5的写法,无法自己抛出错误,需要放在try-catch里面
try {
    Object.defineProperty()
} catch (e) {}

// ES6
if (Reflect.defineProperty()) { // boolean

} else {

}

3. 命令式操作->函数式操作

// 判断对象是否有assign方法
// ES5命令式
console.log('assign' in Object) // true
// ES6函数式
console.log(Reflect.has(Object, 'assign'))// true

4. 与Proxy对象的方法一一对象

//保护下划线属性
let user = {
    name: 'kaka',
    age: 20,
    _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) // undefined
for (let key in user) {
    console.log(key) // name
}

5. apply

// 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)) // 6
console.log(sum.call(null, 1, 2, 3)) // 12
console.log(sum.apply(null, [1, 2, 3])) // 12

总结

Reflect的出现是为了让Object方法更加规范。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值