ECMAScript-Reflect

本文深入探讨了JavaScript中的Reflect API,它将Object内置方法移至Reflect,改进了方法返回结果,使操作更具函数行为。通过示例展示了Reflect定义属性、获取属性、设置属性等方法的使用,并对比了与Proxy对象的对应方法。此外,还展示了如何利用Reflect实现数据访问限制和属性操作拦截。
摘要由CSDN通过智能技术生成

一、Reflect

Reflect相关的静态方法:

  • 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)
1. 将Object属于语言内部的方法放到Reflect
// Object -> Reflect
// 为什么这么干,为Object减负,将Object下面的一些方法,转移到Reflect下面
let obj = {}
let newVal = ''
Reflect.defineProperty(obj, 'name', {
    get() {
        return newVal
    },
    set(val) {
        console.log('set') // set
        newVal = val
    }
})
obj.name = 'es'
console.log(obj.name) // es
2. 修改某些Object方法的返回结果,让其变得更合理
// 比如Object.defineProperty()方式,如果不可定义,则会抛出异常
// 那对应的处理方式,只能try-catch
try {
  Object.defineProperty()
} catch (e) {
  
}

// Reflect.defineProperty()返回的是布尔值
if (Reflect.defineProperty()) {
  
} else {
  
}
3. 让Object操作变成函数行为
// Object的很多操作都是命令式的
console.log('assign' in Object) // true

// Reflect方式
console.log(Reflect.has(Object, 'assign')) // true
4. Reflect对象的方法与Proxy对象的方法一一对应
let user = {
    username: 'zhangsan',
    age: 34,
    _pwd: '****'
}

user = new Proxy(user, {
    get(target, prop) {
        if (prop.startsWith('_')) {
            throw new Error('不可访问')
        } else {
            // return target[prop]
            // 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, props)
            return true
       }
    },
    ownKeys(target) {
       // return Object.keys(target).filter( key => !key.startsWith('_'))
       return Reflect.ownKeys(target).filter( key => !key.startsWith('_'))
    }
})

console.log(user.age) // 34
// console.log(user._pwd) //  Uncaught Error: 不可访问
// user._pwd = '123' // Uncaught Error: 不可访问
//  delete user._pwd // 不可删除
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]))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值