ES6 Reflect
创始人
2024-03-18 11:30:24
0

在这里插入图片描述

前言

  此文总结了Reflect对象的部分语法,对比了与Object方法的差异性,希望对你有用。

语法

  ReflectMath类似,都是JavaScript内置对象,提供了工具方法。

typeof Reflect // object

get

  Reflect.get(target, property, receiver) 用于读取对象属性,其中target为目标对象,property为属性名称。

var object = { x: 1 }Reflect.get(object, 'x') // 1

  读取目标对象的访问器属性时,访问器getterthis上下文就是参数receiver。未指定参数receiver,默认为目标对象。

var object = {y: 1,get x() {return this},
}
var receiver = {}Reflect.get(object, 'x') === object // true
Reflect.get(object, 'x', receiver) === receiver // true

set

  Reflect.set(target, property, value, receiver) 用于设置对象属性,其中target为目标对象,property为属性名称,value为属性值。

var object = { x: 1 }Reflect.set(object, 'x', 2)object // {x: 2}

  类似的,访问器setterthis上下文就是参数receiver,默认为目标对象。

var object = {y: 1,set x(v) {this.y = v},
}
var receiver = {}Reflect.set(object, 'x', 2)
object // {y: 2}Reflect.set(object, 'x', 3, receiver)
receiver // {y: 3}

has

  Reflect.has(object, property) 判断对象是否有此属性,本质上与in操作符功能相同。

var object = { x: undefined }Reflect.has(object, 'x') // true

deleteProperty

  Reflect.deleteProperty(target, property) 用于删除对象属性,本质上与delete操作符功能相同。

var object = { x: 1 }Reflect.deleteProperty(object, 'x')object // {}

ownKeys

  Reflect.ownKeys(target) 返回对象自身所有属性,等价于Object.getOwnPropertyNames(target)Object.getOwnPropertySymbols(target)之和。

var object = { x: 1, [Symbol('y')]: 2 }Object.defineProperty(object, 'z', {value: 3,enumerable: false,
})Reflect.ownKeys(object) // ['x', 'z', Symbol(y)]

getOwnPropertyDescriptor

  Reflect.getOwnPropertyDescriptor(target, property) 用于获取对象属性描述符。

var object = { x: 1 }Reflect.getOwnPropertyDescriptor(object, 'x')
// {
//   configurable: true,
//   enumerable: true,
//   value: 1,
//   writable: true,
// }

  与Object.getOwnPropertyDescriptor不同之处在于,target为非对象时,Object版本静默失败并返回undefined。而Reflect版本则抛出错误,提示开发者注意参数类型。

Object.getOwnPropertyDescriptor(1, 'x')
// undefinedReflect.getOwnPropertyDescriptor(1, 'x')
// Uncaught TypeError: Reflect.getOwnPropertyDescriptor called on non-object

defineProperty

  Reflect.defineProperty(target, property, descriptor) 用于定义对象属性,其中target为目标对象,value为属性名称,descriptor为属性描述符。

var object = {}Reflect.defineProperty(object, 'x', { value: 1 })Reflect.getOwnPropertyDescriptor(object, 'x')
// {
//   configurable: false,
//   enumerable: false,
//   value: 1,
//   writable: false,
// }

  若属性定义失败,Object版本将抛出错误,而Reflect版本将返回false

var object = Object.freeze({})Reflect.defineProperty(object, 'x', { value: 1 })
// falseObject.defineProperty(object, 'x', { value: 1 })
// Uncaught TypeError: Cannot define property x, object is not extensible

preventExtensions

  Reflect.preventExtensions(target) 阻止对象拓展。

var object = {}Reflect.preventExtensions(object)Reflect.isExtensible(object) // false

  类似的,target为非对象时,Object版本静默失败,而Reflect版本将抛出错误。

Object.preventExtensions(1)
// 1Reflect.preventExtensions(1)
// Uncaught TypeError: Reflect.preventExtensions called on non-object

isExtensible

  Reflect.isExtensible(target) 判断对象是否可拓展。

var object = {}Reflect.preventExtensions(object)Reflect.isExtensible(object) // false

  若参数为非对象,Reflect版本将抛出错误,而Object版本则静默失败并返回false。不合理之处在于参数为非对象,讨论是否可拓展并没有任何意义。

Reflect.isExtensible(1)
// Uncaught TypeError: Reflect.isExtensible called on non-objectObject.isExtensible(1)
// false

getPrototypeOf

  Reflect.getPrototypeOf(target) 获取对象原型。

Reflect.getPrototypeOf({}) === Object.prototype // true

  参数target为非对象时,Object版本存在类型转换,而Reflect版本将抛出错误。

Object.getPrototypeOf(1) === Number.prototype
// trueReflect.getPrototypeOf(1)
// Uncaught TypeError: Reflect.getPrototypeOf called on non-object

setPrototypeOf

  Reflect.setPrototypeOf(target, prototype) 用于设置原型,返回值为布尔值。

var object = {}Reflect.setPrototypeOf(object, null)Reflect.getPrototypeOf(object) // null

  类似的,参数target为非对象时,Object版本静默失败并返回target,而Reflect版本将抛出错误。

Object.setPrototypeOf(1, null)
// 1Reflect.setPrototypeOf(1, null)
// Uncaught TypeError: Reflect.setPrototypeOf called on non-object

apply

  Reflect.apply(target, thisArg, args) 用于调用函数,其中target为目标函数,thisArg为函数被调用时的上下文对象thisargs为函数参数。

function fn(x, y) {return this.v + x + y
}Reflect.apply(fn, { v: 1 }, [2, 3]) // 6

  若函数apply属性被占用,运行apply方法绑定this将抛出错误。

function fn(x, y) { return x + y }fn.apply = 1fn.apply(null, [3, 4])
// Uncaught TypeError: fn.apply is not a function

  替换为原型apply方法可规避,但语义不明显。

Function.prototype.apply.call(fn, null, [3, 4]) // 7

  而Reflect.apply执行方式则更简洁清晰。

Reflect.apply(fn, null, [3, 4]) // 7

construct

  Reflect.construct(target, args, newTarget) 与new操作符行为类似,其中target为构造函数,args为函数参数。

function F(x, y) {this.x = xthis.y = y
}Reflect.construct(F, [1, 2]) // F {x: 1, y: 2}

  参数newTarget有两个用处,第一个是指定新对象的原型为newTarget的原型对象。

function F() {}
function NT() {}var object = Reflect.construct(F, [], NT)Reflect.getPrototypeOf(object) === NT.prototype // true

  除此之外,原构造函数内部new.target会被指向newTarget函数。

function F() {console.log(new.target === NT) // true
}
function NT() {}Reflect.construct(F, [], NT)

小结

  Reflect对象的设计目的主要包括。

  • 语言内部的元编程行为,统一移动至Reflect,未来新的元编程行为将只添加到Reflect
  • Object部分函数的行为不合理,在Reflect版本进行修正
  • 符合函数式编程,语义更清晰
  • ProxyReflect结合在代理同时还能保持默认行为

🎉 写在最后

🍻伙伴们,如果你已经看到了这里,觉得这篇文章有帮助到你的话不妨点赞👍或 Star ✨支持一下哦!

手动码字,如有错误,欢迎在评论区指正💬~

你的支持就是我更新的最大动力💪~

GitHub / Gitee、GitHub Pages、掘金、CSDN 同步更新,欢迎关注😉~

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
【Ctfer训练计划】——(三... 作者名:Demo不是emo  主页面链接:主页传送门 创作初心ÿ...