【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反射机制 的相关文章

  • 在 play 框架中将 javascript 变量转换为 scala

    我在 javascript 中有一些变量 var something 1 var url CSRF routes Some thing something 我在编译期间收到错误 因为 某物 换句话说 不引用 javascript 变量 编译
  • 我可以补间 D3 弧的结束角度,但不能补间起始角度。我究竟做错了什么?

    我只是在玩这个演示并自己重新创建它 http bl ocks org mbostock 5100636 http bl ocks org mbostock 5100636 我可以定义一个新的 endAngle 并且它会很好地制作动画 但现在
  • 在react中读取excel文件

    我正在尝试读取 excel 文件并使用 XLSX 将其转换为 JSON 格式 但无法做到这一点 当文件位于本地计算机上时 任何人都可以建议转换方法吗 通过输入选择您本地机器的 Excel 表 在那之后 您的 Excel 数据将显示为 JSO
  • 如何全局公开 es6 模块

    我需要编写一个可在全局窗口上使用的模块 我使用 es6 创建模块 我定义的每个类都有它自己的文件 我正在使用 webpack 来 babelify 并捆绑这些类 我的模块的入口点也是包含要公开的全局的文件 我尝试了各种方法来实现这一点 包括
  • Angular 模板调用函数可以返回 Promise

    Angular 的 q 文档 http docs angularjs org api ng 24q说 q 承诺被模板引擎以角度方式识别 这意味着在模板中 您可以将附加到范围的承诺视为结果值 Angular 的视图模板还允许您计算表达式 这意
  • Chart.JS 工具提示回调标签和标题 (v3.5)

    请注意 v2 有很多答案 这是 v3 的 我正在尝试设置工具提示label and title对于圆环图 Code Create the donut chart donut new Chart questions positivity do
  • 电话链接在 iframe 中不起作用,但在 iOS 9 Web 中的 div 中起作用。如何使电话链接在 iOS 9 safari 中正常工作?

    您好 我正在尝试 iOS9 中 iframe 内的电话链接 iOS9 中的 safari 中无法打开手机应用程序 当我在里面尝试相同的链接时 它就在那里工作 我正在尝试下面的锚标记 将此代码放入 div 中时会打开手机应用程序 但同样的代码
  • ionic 2 从 json 填充选择选项

    我正在尝试动态填充ion select带有 json 对象的下拉列表 我的 html 组件如下所示
  • 如何在 d3.scale.ordinal() 中指定域?

    var W 100 var H 200 var data v 4 v 8 v 15 v 16 v 23 v 42 var x d3 scale linear domain 0 max x range 0 W var y d3 scale o
  • 如何防止 Ajax/javascript 结果在浏览器中缓存?

    如何防止浏览器缓存Ajax结果 我有事件触发的 Ajax 脚本 仅当浏览器数据被清除时才显示结果 在 IE6 和 Firefox 3 0 10 中测试 随机 URL 可以工作 但它是一种 hack HTTP 内置了应该可以工作的解决方案 尝
  • 如何让 ckeditor 停止删除空 div

    stackoverflow 上也有类似的问题 但这些问题的答案对我不起作用 所以请不要将其标记为重复 在我的 cms 中 我希望人们能够添加 SPA 单页应用程序 内容页面 此类应用程序通常只有一个具有某些属性的 div 并且使用 java
  • 如何从 Selectize 中删除项目?

    有什么方法可以从 Selectize 中删除项目吗 这是我的示例列表 AMNT QTY NA 当我经过时NA它应该删除特定项目 fn removeSelectorValue function value var selectize this
  • 实现github.com文件无缝文件导航

    我刚刚在浏览 github 存储库时注意到最近的变化 当您选择文件或文件夹时 新文件会滑入并推出旧文件 使用 jquery 很容易做到这一点 但真正不同的是 URL 本身实际上发生了变化 因此书签仍然有效 我一直在努力为我正在开发的图书导航
  • 如何访问打字稿中的组件

    我有一个基本的 Angular 应用程序 如下所示 app component html h1 Test Umgebung h1 div div
  • 使用 JavaScript 检测硬重新加载

    为了澄清 I am not试图区分刷新和重新加载 因此这不是重复的刷新与重新加载 https stackoverflow com questions 5004978 check if page gets reloaded or refres
  • Firebase 如何更新多个子项?

    我有很多这样的孩子的父母 Parent childe1 data childe2 data childe3 data childe4 data childe5 data 我怎样才能更新孩子们的信息 childe1 childe2 child
  • 双向数据绑定(Angular)与单向数据流(React/Flux)

    上周 我一直在试图弄清楚如何双向数据绑定 Angular https docs angularjs org guide databinding and 单向数据流 React Flux https youtu be i 969noyAM是不
  • 脚本内的角度范围

    我们可以使用脚本标记内范围中定义的角度变量 如下所示 HTML 代码 div div JS CODE function AngularCtrl scope scope user name John 我只是得到 scope 未定义 有人可以帮
  • 如何禁用 Aloha 编辑器工具栏?

    有没有办法像侧边栏一样禁用 Aloha 的 ExtJS 工具栏 Aloha settings modules aloha aloha jquery editables editable jQuery sidebar disabled tru
  • setInterval 会导致浏览器挂起吗?

    几年前 我被警告不要使用setInterval很长一段时间 因为如果被调用的函数运行时间超过指定的时间间隔 可能会导致浏览器挂起 然后无法跟上 setInterval function foo bar i 1 现在 我知道在循环中添加大量代

随机推荐

  • 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概述