Object reflection in JavaScript

Today a small reflection about the object reflection. I’ll try to be concise.

Object reflection in JavaScript

Reflection of objects is not just a curiosity, but also a tool, which we can meet more often than we think. And it may turn out to be this, what we need when we stuck with some issue.

The reflection mechanism allows us to work with the code in the same way, as with the data.

This means that we can operate on the code as on the data, and create our own structures modifying the standard operation of the language.

Reflection is usually encountered in high-level languages​​, most often based on a virtual machine. Such techniques are probably well known by developers of languages such as Python or Ruby.

When necessary, also in the JavaScript code we can use the object reflection!

The main thing in this case is an overview of the elements, on which our object is built. And this is what we will do now.

Viewing object components

This is possible through the Object.getOwnPropertyNames method.

Example — Math object:

alert(Object.getOwnPropertyNames(Math));

The result will be similar to following:

[toSource,abs,acos,asin,atan,atan2,ceil,cos,exp,floor,imul,fround,log,max,min,pow,random,
round,sin,sqrt,tan,log10,log2,log1p,expm1,cosh,sinh,tanh,acosh,asinh,atanh,trunc,sign,cbrt,
E,LOG2E,LOG10E,LN2,LN10,PI,SQRT2,SQRT1_2]

With just one line of code we received really valuable information that can be further processed.

This the one of the simplest examples about using reflection in JavaScript. A simple code that quickly shows us a “cheat sheet” about this, what we’re working.

Of course we can try this for other objects, like String or Number, and our own objects!

And more importantly — for those objects, that have been developed by other programmers; compressed, undocumented … and who knows what else. And it’s good to be ready for anything.

Object reflection in JavaScript — one step further

Another thing we can do is filtering. Let’s write the code that processes the object and returns the available methods:

function getMethods(obj) {
    var props = Object.getOwnPropertyNames(obj);
    var methods = props.filter(function(property) {
        return typeof obj[property] == 'function';
    });

    return methods;
}

alert(getMethods(Math));

The result, which I had in Firefox:

[toSource,abs,acos,asin,atan,atan2,ceil,cos,exp,floor,imul,fround,log,max,min,pow,random,
round,sin,sqrt,tan,log10,log2,log1p,expm1,cosh,sinh,tanh,acosh,asinh,atanh,trunc,sign,cbrt]

Now just change the line:

…
return typeof obj[property] == 'function';
…

to

…
return typeof obj[property] != 'function';
…

and we get everything, what is not a function in our object, e.g.:

E,LOG2E,LOG10E,LN2,LN10,PI,SQRT2,SQRT1_2

The next method allows us to determine, if the object has this, what we are looking for.

The hasOwnProperty method

And more specifically our_object.hasOwnProperty(), which returns a boolean value indicating whether the object has the interesting us property or method.

We can use it for example to avoid errors, by checking method / property availability as first. Thus we can get an even higher level of control over our code.

Let’s consider an example.


function getCarData() {

    var myCar = {
        name: "VW",
        model: "Bora",
        power_hp: 110,
        getColor: function () {
            // …
        }
    };

    alert(myCar.hasOwnProperty('constructor')); // false
    alert(myCar.hasOwnProperty('getColor')); // true
    alert(myCar.hasOwnProperty('megaFooBarNonExisting')); // false

    if (myCar.hasOwnProperty('power_hp')) {
        alert(typeof(myCar.power_hp)); // number
    }
}

getCarData();

Before displaying the type of power_hp element, we check if such element exists. The same for methods: the getColor method is available, but there is no megaFooBarNonExisting method. However it’s not a problem in this code.

Summary

We could create a more complex examples, but the main point is to present the reflection mechanism and show how to work with this in JavaScript. From the developer’s point of view, this is interesting topic, also in the context of other programming languages.

Thank you!