QAT Insights

Highlighting recent QAT solution releases, insights, service and industry information, upcoming events, case studies, and press releases.

Runtime modification of JavaScript Objects

August15

Like many of us, I never learned the JavaScript formally but started dabbling in it, using a similar-looking language (Java) as base for my coding style. Here’s another feature that seems quite simple but it took me a while to realize how powerful it really is because of my Java bias. In Java or .Net, information about an object can be gathered and generic operations executed at runtime via a mechanism called Reflection. Since it adds a certain overhead and is cumbersome to code, it is used rarely in everyday code (although frameworks like Spring frequently use it internally). In JavaScript, on the other hand, it’s not only very easy to discover object details at runtime and perform operations in a generic way, but it’s even possible to add and remove object properties themselves. Now I usually think of JavaScript objects as maps or associative arrays. Since JavaScript methods are simply objects themselves, they are just another property or “key”. The different tasks are made easier by several syntax options:

Let’s start with a simple object with a few properties:

var obj = new Object();
obj.property1 = 1;
obj.property2 = "two"; 

 

is equivalent to:

var obj = {};
obj["property1"] = 1;
obj["property2"] = "two";

and results in the same object as:

var obj = {
 property1: 1,
 property2: "two"
}

Let’s add and call a function:

obj.property3 = function(){ alert("Property3")};
obj.property3();

or

obj["property3"] = function(){ alert("Property3")};
obj["property3"]();

Now let’s remove a property:

delete obj.property1; 

or

delete obj["property1"];

The array/map syntax object[key] is often more cumbersome and longer than object.property but it is very handy when the property name is not known at coding time (for example the value of a variable). For numeric “keys” like in a traditional array, this is the only way to access them.

Let’s copy the properties of our object to another – we don’t even have to know what exactly they are:

var obj2 = {};
for (var prop in obj){
	obj2[prop] = obj[prop];
}

We also can use expressions to derive the name of a property. This example also checks the existence of a property before accessing it:

for (var i = 0; i < 4; i++){
        if (typeof obj["property" + i] != 'undefined') {
                alert(obj["property" + i]);
        }
}

Of course, there are drawbacks: Since almost anything is possible, a JavaScript IDE can never tell for sure whether you simply misspelled a property name or whether this would actually work at runtime. It is virtually impossible for the IDE to predict all properties of a given objects for auto-completing names etc. It also makes debugging a lot harder.

There is a place and time for everything. In my code, I often have objects that are based on prototype/class hierarchies with clearly defined sets of properties and functions. I use them as I would use instances of classes in Java and .Net. Actually, mimicking inheritance mechanisms in JavaScript often utilizes the mechanisms outlined above during the creation of the objects, but that is hidden from the actual business code. It is typically the data objects that I modify at runtime.

Anke

posted under JavaScript

Comments are closed.