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!