Reflection in Javascript

by Nzeteh Nwakaego

Fasae Oluwakemi
Devcrib
5 min readDec 14, 2017

--

Image credit: Pexels

The word reflection depicts an object which doesn’t have an attribute of it’s own but would exhibit the attribute of any object it is exposed to. Think of reflection in ES6 as a static object that you can’t new up nor call, and all of it’s methods are static. Using reflection, a class can query or inspect another class in the same system (or itself). It can get the names of all the members of the class and can even display them.

Until Java, there was no such feature in any programming language that enabled a class to self-inspect and manipulate its member attributes and methods. Since then, other languages as PHP and .NET have implemented their own reflections. JavaScript does provide an amount of reflective functionality, although limited when compared to the above mentioned languages.

The ES6 Reflect object isn’t a function object, doesn’t have a [[Construct]] internal method i.e. can't use new, and doesn't have a [[Call]] internal method i.e. can't invoke it as a function.

Uses of Reflection

In an event where a programmer realizes that he wants to make use of a class after he has long passed it, to locate the class, load modules that are listed in the assembly, create an instance of the class, query an object or get an interface of the attributes and services of a class, such programmer would have to write very many lines of codes. But with reflection, he could easily locate the class and query or inspect the class.

Reflection in ES6

JavaScript already has reflection features in ES5 even though they were not named reflection either by specification or by the community. Methods such as Array.isArray , Object.getOwnPropertyDescriptor and Objects.keys acted much like the features reflection exhibits. The Reflect built-in in ES6 now houses methods in this category. The new feature makes a lot of sense because it provides a dedicated interface that exposes most reflection methods since Object is meant to be a base prototype and not a repository of reflection methods. The _traps in ES6 proxies are mapped one-to-one to the Reflect API. For every trap, there's a matching reflection method in Reflect.

The Reflect.deleteProperty(target, key) is equivalent to the delete target[key] expression but it was required in ES5 to create a utility method that wrapped delete on behalf of the programmer.

Comparing Object to Reflect, theReflect return value is more meaningful than that of `Object . The Reflect.defineProperty returns a boolean value indicating whether the property was successfully defined meanwhile, the Object.defineProperty counterpart returns the object it got as its first argument, which wouldn't be very useful.

The Methods of the Reflect Object

The ES6 global Reflect object exposes all the new methods for the object reflection. The Reflect object wraps all the methods of the ES6 Reflect API which makes it look well organized.

Reflect.apply(function, this, args) method

This method is used to invoke a function with a given this value. The invoked function is the target function. It takes in three arguments: the first represents the target function, the second (which is optional) represents the value of this inside the target function and the third argument is an array object.

Reflect.construct(constructor, args, prototype) method

The Reflect.construct() method is used to invoke a function as a constructor.It's similar to the new operator. The function that will be invoked as a constructoris called as the target constructor. It takes three arguments: the first argument is the target constructor, the second argument is an array, specifying the arguments of the target constructor and the third argument is another constructor whose prototype will be used as the prototype of the target constructor. The second and the third are optional.

Reflect.defineProperty(object, property,descriptor) method

The Reflect.defineProperty() method defines a new property directly on anobject, or modifies an existing property on an object. It returns a Boolean valueindicating whether the operation was successful or not. It takes three arguments: the first argument is the object that is used to define or modify a property, the second argument is the symbol or name of the property that is to be defined or modified and the third argument is the descriptor for the property that being defined or modified.

Reflect.deleteProperty(object, property) method

The Reflect.deleteProperty() method is used to delete a property of an object. It's the same as the delete operator.This method takes two arguments, that is, the first argument is the reference to theobject and the second argument is the name of the property to delete. The Reflect.deleteProperty() method returns true if it has deleted the property successfully.Otherwise, it returns false .

Reflect.enumerate(Object) method

The Reflect.enumerate() method takes an object as argument and returns aniterator object that represents the enumerable properties of the object. It also returnsthe enumerable inherited properties of an object. The Reflect.enumerate() method is similar to the for…in loop . The Reflect.enumerate() method returns an iterator, whereas the for…in loop iterates over enumerable properties.

Reflect.get(object, property, this) method

The Reflect.get() method is used to retrieve the value of an object's property.The first argument is the object and the second argument is the property name.If the property is an accessor property, then we can provide a third argumentwhich will be the value of this inside the get function.

Reflect.set(object, property, value, this) method

The Reflect.set() method is used to set the value of an object's property. The firstargument is the object, the second argument is the property name, and the thirdargument is the property value. If the property is an accessor property, then we canprovide a fourth argument which will be the value of this inside the set function.The Reflect.set() method returns true if the property value was set successfully.Otherwise, it returns false .

Reflect.getOwnPropertyDescriptor(object.property) method

The Reflect.getOwnPropertyDescriptor() method is used to retrieve the descriptor of an object's property. The Reflect.getOwnPropertyDescriptor() method is same asthe Object.getOwnPropertyDescriptor() method.

The Reflect.getOwnPropertyDescriptor() method takes two arguments. The first argument is the object and the second argument is the property name.

Reflect.getPrototypeOf(Object) method

The Reflect.getPrototypeOf() method is used to retrieve prototype of an objectthat is, the value of the internal [[prototype]] property of an object. The Reflect.getPrototypeOf() method is same as the Object.getPrototypeOf() method.

Reflect.setPrototypeOf(object, prototype) method

The Reflect.setPrototypeOf() is used to set the internal [[prototype]] property's value of an object. The Reflect.setPrototypeOf() method will return true if the internal [[prototype]] property's value was set successfully. Otherwise, it will return false .

Reflect.has(object, property) method

The Reflect.has() is used to check if a property exists in an object. It also checksfor the inherited properties. It returns true if the property exists. Otherwise it'dreturn as false . It's same as the in operator.

Reflect.isExtensible(object) method

The Reflect.isExtensible() method is used to check if an object is extensible ornot, that is, if we can add new properties to an object. An object can be marked as non-extensible using the Object.preventExtensions() , Object.freeze() and the Object.seal() methods. The Reflect.isExtensible() method is same as the Object.isExtensible() method.

Reflect.preventExtensions(object) method

The Reflect.preventExtensions() is used to mark an object as non-extensible.It returns a Boolean, indicating whether the operation was successful or not. It's same as the Object.preventExtensions() method.

Reflect.ownKeys(object) method

The Reflect.ownKeys() method returns an array whose values represent the keysof the properties of an provided object. It ignores the inherited properties.

The Reflector object has a lot of advantages which should be harnessed in locating classes in programming. Enjoy the benefits.

References

https:///h3manth.com

https://ponyfoo.com/articles

https://mobile.htmlgoodies.com

Learning ECMAScript, Narayan Prusty.

--

--