作为开发人员,您需要能够创建可以处理动态代码的系统和应用程序。 这些程序应该能够在运行时操作变量、属性和对象方法。 为此,一个新的全局对象, Reflect,能够处理简单的代码操作,是在 ES6 中引入的。
本文的目的是帮助您更好地理解 Reflect在 JavaScript 中以及如何使用提供的各种方法。 Reflect使您能够轻松地修改现有对象的功能,同时仍提供其默认行为。
目录:
什么是 JavaScript 反射?
Proxy 构造函数和 Reflect 有什么区别?
使用反射 API 方法
Reflect.construct()
Reflect.apply()
Reflect.defineProperty()
Reflect.get()
Reflect.getPrototypeOf()
Reflect.set()
Reflect.deleteProperty()
Reflect.isExtensible()
Reflect.ownKeys()
Reflect.getOwnPropertyDescriptor()
Reflect.has()
JavaScript Reflect is an inbuilt ES6 global object that provides the ability to manipulate properties, variables, and object methods at runtime. It is not a constructor, therefore you cannot use the new operator with it.
Proxy and Reflect were both introduced in ES6 and are used for performing tasks, but they are a bit different.
Unlike Reflect, JavaScript’s Proxy does not have any properties. Instead, it wraps around another object and intercepts its operations. Meanwhile, Reflect is an inbuilt object that simplifies the creation of Proxy and makes it possible to call internal methods.
Proxy takes only two arguments:
target: The object that the Proxy will wrap
handler: The Proxy configuration that will intercept target operations
这是一个例子:
const profile = { name: 'Pascal', age:23 } const handler = { get(target, prop, receiver) { if (target[prop]) { return target[prop] } return `"${prop}" prop don't exist on this object !` } } const profileProxy = new Proxy (profile, handler) console.log(profileProxy.name) // Pascal console.log(profileProxy.profession) // "profession" prop don't exist on this object !
上面的例子等价于 Reflect.get(),这将在本指南的后面部分进行介绍,但是, Reflect.get()技术更简单,更直接。
让我们仔细看看这些方法 Reflect目的。 所有这些方法都是静态的,也就是说,它们只能在 Reflect对象而不是任何实例。
超过 20 万开发人员使用 LogRocket 来创造更好的数字体验 Learn more →
The new operator and Reflect.construct() method are comparable and are similar to new target(...args), but with the option to choose a different prototype. Reflect.construct() accepts three arguments:
target: The function to be invoked
args: An array of arguments
newTarget: An optional constructor whose prototype should be utilized; if it is not specified, its default value is target
Consider the following example:
function summation(x,y,z){ this.add = x + y +z } const sum = Reflect.construct(summation, [1,2,3,4,5]) console.log(sum) // Result: summation {add: 6}
Reflect.construct()产生一个新的实例 target或者 newTarget(如果指定),它是用提供的参数数组构造的, args. 引进前 Reflect.construct(),我们将结合构造函数和原型来创建一个对象: Object.create().
Reflect.apply()是一种使用提供的参数调用目标函数的简单直接的方法。 它接受三个参数:
target: 要调用的函数
thisArgument: 这 this需要值来调用 target功能
args: 一个包含参数的数组 target应该被调用
这是一个例子:
/* Return the highest value in the array */ const arr = [3,5,20,3,31] const a = Reflect.apply(Math.max, undefined, arr) console.log(a) // Result: 31
前 Reflect.apply()被介绍了,我们可以使用 function.prototype.apply()执行类似任务的方法,如下所示:
const arr = [3,5,20,3,31] const a = Function.prototype.apply.call(Math.max, undefined, arr); console.log(a) // Result: 31
要创建或编辑对象的属性,请使用 Reflect.defineProperty()方法。 它返回一个布尔值,指示属性是否已成功定义。 该方法接受三个参数:
target:将在其上定义属性的对象
propertyKey:要创建或编辑的属性的名称
attributes:正在定义的属性的属性
请参见以下示例:
Don't miss a moment with The Replay, a curated newsletter from LogRocket
Learn how LogRocket's Galileo cuts through the noise to proactively resolve issues in your app
Use React's useEffect to optimize your application's performance
Switch between multiple versions of Node
Discover how to animate your React app with AnimXYZ
Explore Tauri, a new framework for building binaries
Compare NestJS vs. Express.js
const obj = {} Reflect.defineProperty(obj, 'prop', {value: 70}) console.log(obj.prop) // Result: 70
As the name implies, Reflect.get() is used to retrieve a property from an object. It accepts three arguments:
target: The object to be targeted
propertyKey: The name of the property to obtain
receiver (optional): If a getter is encountered, the this value is passed as the receiver for the call to the target object
这是一个例子:
// with array const b = [10,11,12,13,14] console.log(Reflect.get(b, 2)) // Result: 12 // with object const obj = {name: "Pascal", age: 23} console.log(Reflect.get(obj, 'age')) // Result: 23
这 Reflect.getPrototypeOf()函数返回所提供目标的原型,很像 Object.getPrototypeOf(). 此方法只接受一个参数:
target:我们要获取其原型的对象
请参见以下示例:
const profile = { name: 'Pascal' }; const pro = Reflect.getPrototypeOf(profile); console.log(pro);
The Reflect.set() method is used to assign a value to an object property. It returns true to indicate that the property was set successfully. This function takes four arguments:
target: The object on which the property is to be set
key: The property’s name
value: The value that will be allocated
receiver(optional): If a setter is found, the this value must be used to call the target
Here’s an example:
const arr1 = []; Reflect.set(arr1, 0, 'first'); Reflect.set(arr1, 1, 'second'); Reflect.set(arr1, 2, 'third'); console.log(arr1);
Reflect.delete Property() is a method for removing a property from an object. If the property is correctly deleted, it returns true. 这个函数有两个参数:
target: 物体
key:要删除的属性名称
请参见以下示例:
Reflect.deleteProperty(obj3, 'age'); console.log(obj3)
Reflect.isExtensible(), 喜欢 Object.isExtensible(), 是一种检测对象是否可扩展的方法(即,是否可以向其添加其他属性)。 Reflect.isExtensible()返回一个布尔值以指示目标是否可扩展。 它只考虑一个论点:
target:要检查可扩展性的对象
这 Reflect.preventExtensions()方法可用于防止对象变得可扩展,即防止向对象添加新属性。
请参见以下示例:
const user = { name: "John Deeman" }; console.log(Reflect.isExtensible(user)) // true // block extension Reflect.preventExtensions(user); console.log(Reflect.isExtensible(user)) // false
这 Reflect.ownKeys()方法基本上返回一个包含目标对象的属性键的数组。 它只考虑一个论点:
target: 从中获取密钥的对象
这是一个例子:
const obj = { car: "Rolls Royce", color: "black" }; const array1 = []; console.log(Reflect.ownKeys(obj)); // ["car", "color"] console.log(Reflect.ownKeys(array1)); // ["length"]
这 Reflect.getOwnPropertyDescriptor()方法返回一个描述符,该描述符定义如何配置给定对象的特定属性。 它需要两个参数:
target: 要搜索属性的对象
key:需要描述的属性的名称
请参见以下示例:
const obj = { car: "Rolls Royce", color: "black", get (){ return `I have a ${color} ${car} car` } }; console.log(Reflect.getOwnPropertyDescriptor(obj, 'car').value); // "Rolls Royce" console.log(Reflect.getOwnPropertyDescriptor(obj, 'color')); // {value: "black", writable: true, enumerable: true, configurable: true} console.log(Reflect.getOwnPropertyDescriptor(obj, 'color').writable); // true
属性描述符可能包含以下属性:
value: 与属性关联的值
writable: 返回的布尔值 true仅当属性的关联值是可修改的
configurable: 返回的布尔值 true仅当可以修改属性描述符的类型并且可以从相关对象中删除该属性时
enumerable: 返回的布尔值 true仅当属性在相关对象的属性枚举期间出现
这 Reflect.has()方法验证是否在目标对象中定义了属性。 它返回一个布尔值。 Reflect.has()执行与 in运算符并接受两个参数:
target: 属性将被检查到的对象
key:要验证的属性的名称
这是一个例子:
const obj = { name: "Douglas" }; console.log(Reflect.has(obj, 'name')); // true console.log(Reflect.has(obj, 'age')); // false console.log(Reflect.has(obj, 'toString')); // true
在本文中,我们检查了 JavaScript Reflect对象和还讨论了两者的区别 Proxy和 Reflect. 我们还查看了如何使用各种 Reflect方法,包括 Reflect.get()用于返回对象属性的值, Reflect.deleteProperty()用于删除对象的属性,以及 Reflect.ownKeys()用于返回对象的属性键。
调试代码始终是一项乏味的任务。 但是,您对错误了解得越多,修复它们就越容易。
LogRocket 允许您以新颖独特的方式了解这些错误。 我们的前端监控解决方案跟踪用户与您的 JavaScript 前端的互动,让您能够准确找出导致错误的用户所做的事情。
LogRocket 记录控制台日志、页面加载时间、堆栈跟踪、带有标头 + 正文的慢速网络请求/响应、浏览器元数据和自定义日志。 了解您的 JavaScript 代码的影响从未如此简单!