Working with the JavaScript Reflect API
Tags: javascript, webdev
Published: 2022-09-20 16:00:26

**Written by [Pascal Akunne](https://blog.logrocket.com/author/pascalakunne/)✏️**

As a developer, you need to be able to create systems and applications that can handle dynamic code. These programs should have the ability to manipulate variables, properties, and object methods at runtime. To this end, a new global object, [`Reflect`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect), that is capable of handling simple code manipulation, was introduced in ES6. 

The goal of this article is to help you better understand the concept of `Reflect` in JavaScript and how to use the various methods provided. `Reflect` enables you to easily tinker with the functionality of an existing object while still providing its default behavior. 

**Table of Contents:**

*   [What is JavaScript Reflect?](#what-is-javascript-reflect)
*   [What is the difference between the Proxy constructor and Reflect?](#what-is-the-difference-between-the-proxy-constructor-and-reflect)
*   [Using the Reflect API methods](#using-the-javascript-reflect-api-methods)
    *   [`Reflect.construct()`](#reflect-construct)
    *   [`Reflect.apply()`](#reflect-apply)
    *   [`Reflect.defineProperty()`](#reflect-defineproperty)
    *   [`Reflect.get()`](#reflect-get)
    *   [`Reflect.getPrototypeOf()`](#reflect-getprototypeof)
    *   [`Reflect.set()`](#reflect-set)
    *   [`Reflect.deleteProperty()`](#reflect-deleteproperty)
    *   [`Reflect.isExtensible()`](#reflect-isextensible)
    *   [`Reflect.ownKeys()`](#reflect-ownkeys)
    *   [`Reflect.getOwnPropertyDescriptor()`](#reflect-getownpropertydescriptor)
    *   [`Reflect.has()`](#reflect-has)

## What is JavaScript `Reflect`? <a name="what-is-javascript-reflect">

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`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new) operator with it.

## What is the difference between the `Proxy` constructor and `Reflect`? <a name="what-is-the-difference-between-the-proxy-constructor-and-reflect">

`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](https://blog.logrocket.com/use-es6-proxies-to-enhance-your-objects/). 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

Here’s an example:

```javascript
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 !
```

The above example is equivalent to `Reflect.get()`, which is described later in this guide, however, the `Reflect.get()` technique is simpler and more straightforward.

## Using the JavaScript `Reflect` API methods <a name="using-the-javascript-reflect-api-methods">

Let’s take a closer look at the methods of the `Reflect` object. All of these methods are static, i.e., they may only be used on the `Reflect` object and not on any instances.

### `Reflect.construct()` <a name="reflect-construct">

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:

```javascript
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()` produces a new instance of the `target` or `newTarget` (if specified), which was constructed with the supplied array of arguments, `args`. Before the introduction of `Reflect.construct()`, we would combine constructor and prototype to create an object: `Object.create()`.

### `Reflect.apply()` <a name="reflect-apply">

`Reflect.apply()` is a simple and straightforward way to call a target function using the provided parameter. It takes in three parameters:

*   `target`: The function to be invoked
*   `thisArgument`: The `this` value is needed to invoke the `target` function
*   `args`: An array containing the parameters with which `target` should be invoked

Here’s an example:

```javascript
/* 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
```

Before `Reflect.apply()` was introduced, we could use the `function.prototype.apply()` method to perform a similar task, like so:

```javascript
const arr = [3,5,20,3,31]
const a = Function.prototype.apply.call(Math.max, undefined, arr);
console.log(a)
// Result: 31
```

### `Reflect.defineProperty()` <a name="reflect-defineproperty">

To create or edit a property on an object, use the `Reflect.defineProperty()` method. It returns a Boolean value that indicates whether a property was successfully defined. This method takes three parameters:

*   `target`: The object on which the property will be defined
*   `propertyKey`: The name of the property to create or edit
*   `attributes`: The attributes of the properties that are being defined

See the following example:

```javascript
const obj = {}
Reflect.defineProperty(obj, 'prop', {value: 70})
console.log(obj.prop)
// Result: 70
```

### `Reflect.get()`<a name="reflect-get">

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

Here’s an example:

```javascript
// 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()` <a name="reflect-getprototypeof">

The `Reflect.getPrototypeOf()` function returns the prototype of the provided target, much like `Object.getPrototypeOf()`. Only one argument is accepted by this method:

*   `target`: The object of which we want to get the prototype

See the following example:

```javascript
const profile = {  
  name: 'Pascal'  
};  
const pro = Reflect.getPrototypeOf(profile);  
console.log(pro); 
```

### `Reflect.set()` <a name="reflect-set">

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:

```javascript
const arr1 = [];
Reflect.set(arr1, 0, 'first');
Reflect.set(arr1, 1, 'second');
Reflect.set(arr1, 2, 'third');
console.log(arr1);
```

### `Reflect.deleteProperty()` <a name="reflect-deleteproperty">

`Reflect.delete Property()` is a method for removing a property from an object. If the property is correctly deleted, it returns `true`. This function takes two arguments:

*   `target`: The object
*   `ke`y: The name of the property to be deleted

See the following example:

```javascript
Reflect.deleteProperty(obj3, 'age');
console.log(obj3)
```

### `Reflect.isExtensible()`<a name="reflect-isextensible">

`Reflect.isExtensible()`, like `Object.isExtensible()`, is a method that detects if an object is extensible (i.e., whether additional properties may be added to it). `Reflect.isExtensible()` returns a Boolean to indicate whether the target is extensible. It only considers one argument:

*   `target`: The object to be checked for extensibility

The `Reflect.preventExtensions()` method may be used to prevent an object from becoming extensible i.e prevents new properties from ever being added to an object. 

See the below example:

```javascript
const user = {
  name: "John Deeman"
};
console.log(Reflect.isExtensible(user))  
// true

// block extension
Reflect.preventExtensions(user);
console.log(Reflect.isExtensible(user))  
// false
```

### `Reflect.ownKeys()` <a name="reflect-ownkeys">

The `Reflect.ownKeys()` method basically returns an array containing the property keys of the target object. It only considers one argument:

*   `target`: The object from which to get the keys

Here’s an example:

```javascript
const obj = {
  car: "Rolls Royce",
  color: "black"
};

const array1 = [];

console.log(Reflect.ownKeys(obj));
// ["car", "color"]

console.log(Reflect.ownKeys(array1));
// ["length"]
```

### `Reflect.getOwnPropertyDescriptor()` <a name="reflect-getownpropertydescriptor">

The `Reflect.getOwnPropertyDescriptor()` method returns a descriptor that defines how a specific property on a given object is configured. It requires two parameters:

*   `target`: The object to be searched for the property
*   `key`: The name of the property for which a description is required

See the below example:

```javascript
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
```

A property descriptor may contain the following attributes:

*   `value`: The value associated with the property
*   `writable`: A Boolean that returns `true` only if the property's associated value is modifiable
*   `configurable`: A Boolean that returns `true` only if the property descriptor's type may be modified and the property can be removed from the related object
*   `enumerable`: A Boolean that returns `true` only if the property appears during property enumeration on the related object

### `Reflect.has()` <a name="reflect-has">

The `Reflect.has()` method verifies if a property is defined in the target object. It returns a boolean. `Reflect.has()` performs similar operations to the `in` operator and accepts two parameters:

*   `target`: The object to which the property will be checked
*   `key`: The name of the property to verify

Here’s an example:

```javascript
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
```

## Conclusion

In this article, we examined the JavaScript `Reflect` object and also discussed the difference between `Proxy` and `Reflect`. We also looked at examples of how to use various `Reflect` methods, including `Reflect.get()` for returning the value of an object property, `Reflect.deleteProperty()` for deleting an object’s property, and `Reflect.ownKeys()` for returning an object’s property keys.

---

##[LogRocket](https://lp.logrocket.com/blg/signup): Debug JavaScript errors more easily by understanding the context

Debugging code is always a tedious task. But the more you understand your errors the easier it is to fix them.

[LogRocket](https://lp.logrocket.com/blg/signup) allows you to understand these errors in new and unique ways. Our frontend monitoring solution tracks user engagement with your JavaScript frontends to give you the ability to find out exactly what the user did that led to an error.

[![Reproduce JavaScript errors](https://blog.logrocket.com/wp-content/uploads/2020/06/reproduce-javascript-errors.gif)](https://lp.logrocket.com/blg/signup)

LogRocket records console logs, page load times, stacktraces, slow network requests/responses with headers + bodies, browser metadata, and custom logs. Understanding the impact of your JavaScript code will never be easier!

[Try it for free.](https://lp.logrocket.com/blg/signup)