什么是 Reflect?
Reflect 是 ES6 中新增的一个内置对象,用于对 Object 对象操作的补充和增强。在早前的 Object 对象中,一部分方法会抛出异常,比如 Object.defineProperty 在重复定义属性时就会抛出异常;另一部分方法在读取或设置对象属性值时会返回一个字符串或布尔类型值,比如 Object.getOwnPropertyDescriptor 方法就会返回一个自身属性描述对象,而如果属性不存在则返回 undefined。但是 Reflect 对象中的方法则处理的更加优雅,不再抛出异常,而是直接返回一个布尔类型值或抛出 TypeError。
Reflect 主要方法
Reflect.apply(target, thisArg, args)
apply 方法与原生的 Function.prototype.apply 方法类似,传入两个参数:要调用的目标函数 target,以及作为目标函数的 this 对象的对象 thisArg。args 参数则为目标函数调用时传递的参数,以数组形式传入。
// 传统写法 let arr = [3, 0, 1, -1, 5]; Math.max.apply(null, arr); // 使用 Reflect 的写法 Reflect.apply(Math.max, null, arr);
Reflect.construct(target, args)
construct 方法用于直接调用 new 命令,传入两个参数:要实例化的构造器 target 和一个数组 args,其中 args 数组是构造器执行时的参数列表。
-- -------------------- ---- ------- -- ---- -------- ---------- ------ - ---------- - ------ ---------- - ------ - ----- --- - --- ---------- ------- -- -- ------- --- ----- --- - ---------------------- ------- --------
Reflect.defineProperty(target, propertyKey, attributes)
defineProperty 方法与原生的 Object.defineProperty 方法作用相同,用于在目标对象 target 上定义一个新属性或修改已有属性的特性(如 writable、enumerable、configurable、get、set 等),并返回一个布尔类型值表示是否操作成功。
-- -------------------- ---- ------- -- ---- ----- --- - --- -------------------------- ------- - ------ ------- --------- ----- ----------- ----- ------------- ----- --- -- -- ------- --- ----- --- - --- --------------------------- ------- - ------ ------- --------- ----- ----------- ----- ------------- ----- ---
Reflect.get(target, propertyKey, receiver)
get 方法与原生的对象访问属性的方式一致,用于获取目标对象 target 上的某个属性属性值,接收两个参数:属性所在的对象 target 和要获取属性的名称 propertyKey。receiver 参数表示访问时 this 的值,默认为 target 对象本身。
// 传统写法 const obj = {age: 20, name: 'Tom'}; const age = obj.age; // 使用 Reflect 的写法 const obj = {age: 20, name: 'Tom'}; const receiver = {}; const age = Reflect.get(obj, 'age', receiver);
Reflect.set(target, propertyKey, value, receiver)
set 方法与原生的对象操作方式一致,用于修改目标对象 target 上指定属性的值,接收三个参数:属性所在的对象 target、要设置的属性名称 propertyKey,以及要设置的值 value。receiver 参数表示访问时 this 的值,默认为 target 对象本身,该方法会返回一个布尔类型值表示是否操作成功。
// 传统写法 const obj = {age: 20, name: 'Tom'}; obj.age = 22; // 使用 Reflect 的写法 const obj = {age: 20, name: 'Tom'}; const receiver = {}; Reflect.set(obj, 'age', 22, receiver);
Reflect.has(target, propertyKey)
has 方法与原生的 in 操作相同,用于判断一个对象是否拥有某个属性,接收两个参数:属性所在的对象 target 和要判断的属性名称 propertyKey,返回一个布尔类型值表示是否拥有该属性。
// 传统写法 const obj = {age: 20, name: 'Tom'}; const hasAge = 'age' in obj; // 使用 Reflect 的写法 const obj = {age: 20, name: 'Tom'}; const hasAge = Reflect.has(obj, 'age');
Reflect.deleteProperty(target, propertyKey)
deleteProperty 方法与原生的 delete 操作相同,用于删除一个属性,接收两个参数:属性所在的对象 target 和要删除的属性名称 propertyKey,返回一个布尔类型值表示删除成功还是属性根本就不存在。
// 传统写法 const obj = {age: 20, name: 'Tom'}; delete obj.age; // 使用 Reflect 的写法 const obj = {age: 20, name: 'Tom'}; Reflect.deleteProperty(obj, 'age');
Reflect.getOwnPropertyDescriptor(target, propertyKey)
getOwnPropertyDescriptor 方法与原生的 Object.getOwnPropertyDescriptor 方法作用相同,用于获取目标对象 target 上指定属性的描述对象(attribute object),包含属性的特性(如 writable、enumerable、configurable、get、set 等)及值 value。
// 传统写法 const obj = {age: 20, name: 'Tom'}; const des = Object.getOwnPropertyDescriptor(obj, 'age'); // 使用 Reflect 的写法 const obj = {age: 20, name: 'Tom'}; const des = Reflect.getOwnPropertyDescriptor(obj, 'age');
Reflect.setPrototypeOf(obj, prototype)
setPrototypeOf 方法与 Object.setPrototypeOf 方法作用相同,用于设置一个对象的 prototype(原型对象)。
// 传统写法 const obj = {}; Object.setPrototypeOf(obj, Array.prototype); // 使用 Reflect 的写法 const obj = {}; Reflect.setPrototypeOf(obj, Array.prototype);
Reflect.getPrototypeOf(obj)
getPrototypeOf 方法与 Object.getPrototypeOf 方法作用相同,用于获取一个对象的 prototype(原型对象)。
// 传统写法 const obj = {}; const prototype = Object.getPrototypeOf(obj); // 使用 Reflect 的写法 const obj = {}; const prototype = Reflect.getPrototypeOf(obj);
示例代码
下面是使用 Reflect 对象与传统方法的相应示例代码:
-- -------------------- ---- ------- -- ------------- --- --- - ----------- -- - ------ - - -- - ------------------------------ ----- --- ----- -- - -- ----------------- ----- ------ ------- ---- -- --- --- - ----------------------- ------ -- ---- -------- --------------- ---------- -------- -- ---- -- ---------------------- ----- --- - --- --------------------------- ------- - ------ ------ --------- ----- ----------- ----- ------------- ----- --- ---------------------- -- --- -- ----------- ----- --- - ----- --- ----- ------- ----- -------- - --- ---------------------------- ------ ----------- -- -- -- ----------- ----- --- - ----- --- ----- ------- ----- -------- - --- ---------------------------- ------ --- ----------- -- ---- -- ----------- ----- --- - ----- --- ----- ------- ---------------------------- -------- -- ---- -- ---------------------- ----- --- - ----- --- ----- ------- --------------------------------------- -------- -- ---- -- -------------------------------- ----- --- - ----- --- ----- ------- ------------------------------------------------- -------- -- ---------------------- ----- --- - --- --------------------------- ----------------- --------------- ---------- ------- -- ---- -- ---------------------- ----- ------- -- ----- --- - --- ---------- --------------------------------------- --- ------------------- -- ----
总结
通过对于 ES6 中新增的 Reflect 对象的详细讲解,我们可以看出 Reflect 对对象的操作提供了更多的便捷,它与传统方式的差别在于处理方法不再抛出异常而是直接返回布尔类型值或 Error,同时提供了这些基本操作的补充和增强,可谓是一个有力的补充。因此,在实际开发中使用 Reflect 可以提高代码的健壮性以及大大提高编程效率。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/645125afec6000760e3f9492