【ES6】Reflect反射机制

2023-11-20


一、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方法更加规范。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【ES6】Reflect反射机制 的相关文章

随机推荐

  • CocosCretor解决premultipliedAlpha黑边问题

    在官方文档中的说明 premultipliedAlpha 对于是否启动贴图预乘 当图片的透明区域出现色块时 需要关闭该选项 当图片的半透明区域颜色变黑时 需要启用该选项 之前在项目中导出的spine有黑边问题 也就是半透明区域颜色变黑 然后
  • 《软件测试的艺术》第五章 模块(单元)测试

    软件测试的艺术 第五章 模块 单元 测试 5 0 前言 5 1 测试用例设计 5 2 增量测试 5 3 自顶向下测试和自底向上测试 5 3 1 自顶向下的测试 5 3 2 自底向上的测试 5 3 3 比较 5 4 执行测试 5 5 小结 参
  • vite-svg-loader,在项目里轻松使用svg,ts项目需特别注意!

    前言 vite svg loader插件可以让我们像使用vue组件那样使用svg图 使用起来超级方便 安装 npm install vite svg loader save dev 使用 1 vite config ts配置 import
  • 解决Flutter键盘弹起导致与输入框有间距问题(Flutter键盘弹起Scaffold布局流程)解析

    一 在项目中遇到了个如下问题 当页面底部有个输入框 点击弹出键盘时 输入框与键盘之间有一段间距 通过排除 最后找到了问题根源所在 原因是使用了这个屏幕适配框架导致的 此框架通过直接修改FlutterViewConfiguration 的si
  • Spring boot中,feign远程调用api,用@SpringQueryMap接收GET请求参数,自定义QueryMapEncoder处理特殊类型的参数转换

    feign远程调用时 get请求时 如果有特殊的字段类型 用 SpringQueryMap接收参数时 会出现异常 需要自定义QueryMapEncoder 本文例举OffsetDateTime字段类型处理 1 OffsetDateTimeQ
  • 性能测试 —— Tomcat监控与调优:status页监控

    Tomcat服务器是一个免费的开放源代码的Web 应用服务器 Tomcat是Apache 软件基金会 Apache Software Foundation Jakarta 项目中的一个核心项目 由Apache Sun 和其他一些公司及个人共
  • 圆石说│彭一鸣:运用区块链技术赋能实体旅游产业;微软开放6万项专利包括一个开源区块链项目……

    智联招聘 区块链岗位需求主要集中在一线和新一线城市 智联招聘报告显示 从目前区块链职位的城市分布来看 该领域的岗位需求主要集中在一线和新一线城市中 其中 北京 上海和深圳位于第一梯队 职位占比分别达到24 20 和10 杭州 广州和成都紧随
  • spacemacs复制minibuffer的内容到buffer里

    spacemacs复制minibuffer的内容到buffer里 获取当前buffer的绝对路径 spacemacs复制minibuffer的内容到buffer里 不常用 但可以开阔一下视野 即 发现helm里 还有可进一步操作的命令 举例
  • pil_openvcv_scikit-image_tensorflow四种读图方式对比

    文章目录 1 四种不同的库读取jpg图显示 2 评估所读图片的差异 3 简单说明有差异原因 4 同样的流程对png图片进行处理 5 png图片转jpg 5 1 使用PIL进行转换 5 2 使用Opencv进行转换 5 3 使用Tensorf
  • asp.net ajax跨域访问,支持Ajax跨域访问ASP.NET Web Api 2(Cors)的示例教程

    随着深入使用ASP NET Web Api 我们可能会在项目中考虑将前端的业务分得更细 比如前端项目使用Angularjs的框架来做UI 而数据则由另一个Web Api 的网站项目来支撑 注意 这里是两个Web网站项目了 前端项目主要负责界
  • 【图像处理】非线性滤波

    非线性滤波 图像处理中滤波分线性滤波和非线性滤波两种 其中常见的线性滤波有 方框滤波 中值滤波 高斯滤波等 其主要原理就是每个像素的输出值是输入像素的加权和 所以像素的输入与输出成线性关系 线性滤波器易于构造 并且易于从频域响应角度进行分析
  • 【电路设计】220V AC转低压DC电路概述

    前言 最近因项目需要 电路板上要加上一个交流220V转低压直流 比如12V或者5V这种 一般来说 比较常见也比较简单的做法是使用一个变压器将220V AC进行降压 比如降到22V AC 但是很遗憾的是 支持220V的变压器一般体积很大 而板
  • Pycharm常用快捷键

    成长就是将你的一切都变成心静如水 将一切情绪都调整到静音模式 一 Pycharm常用快捷键 查找 CTRL F 全局查找 CTRL shift F 撤销 CTRL Z 缩进 Tab 行首 HOME 快速修正 alt enter 复写代码 C
  • chatgpt赋能python:如何使用Python进行SEO优化

    如何使用Python进行SEO优化 在数字化时代 SEO已经成为一个广泛使用且需求不断增加的领域 虽然有很多工具和技术可以用于SEO 但Python是其中之一 Python是一种现代编程语言 通常用于处理大数据集 自动化任务 Web开发等特
  • Android面试题内存&性能篇

    Android面试题内存 性能篇 由本人整理汇总 后续将继续推出系列篇 如果喜欢请持续关注和推荐 更多内容可以关注微信公众号 Android高级编程 android tech 系列文章目录 Android面试题View篇 Android面试
  • Linux下Memcached的安装步骤

    一 安装gcc yum y install gcc 二 安装libevent wget http www monkey org provos libevent 2 0 12 stable tar gz tar zxf libevent 2
  • 记录下sudo: export: command not found的原因

    今天设置环境变量 输入以下命令 sudo export PATH PATH 路径 路径为arm linux gcc的bin目录 结果提示 sudo export command not found 在网上搜了一下 网友给出了答案 原理是ex
  • vue+java实现在线播放mp4视频

    首先如果本地的mp4视频可以播放 但是在网页就显示视频格式不正确 可能原视频不是mp4格式的 更改后缀名为mp4了 但是在网页上还是无法播放 可以用 ffmpeg转换视频格式 一般遇到格式问题都是视频格式不对 需要专门的工具来转换 java
  • 《Linux系统调用:localtime,setlocale》

    一 介绍 时区 不同国家 有的甚至是同一国家不同地区 使用不同的时区和夏时制 对于要输入和输出时间的程序来说 必须对系统所处的时区和夏时制加以考虑 所有的细节已经由C语言库包办了 时区的定义 时区信息繁琐又多 出于这个原因系统没有将其直接编
  • 【ES6】Reflect反射机制

    文章目录 一 Reflect概述 二 用法详解 1 Object gt Reflect 2 修改Object方法的返回结果 3 命令式操作 gt 函数式操作 4 与Proxy对象的方法一一对象 5 apply 总结 一 Reflect概述