1

I am making an javascript game, featuring several levels, stored in json. When loading, I run a function to "parse" the level object by replacing values that are not present by their default values, or by replacing some values by objects, such as:

//i is the variable I use to loop through the enemies

if (typeof(level.enemies[i].life)=="undefined") {
 level.enemies[i].life=100;
}

if (typeof(level.enemies[i].follow)=="number") {
 level.enemies[i].follow=level.enemies[level.enemies[i].follow];
 // replace the number of the enemy,
 // by a reference to the actual enemy.
}

The problem is that I have a lot of "ifs" similar to these throughout the function, and I am wondering if I somehow can reduce them to a function so I can do this:

replaceByType(level.enemies[i].life,"undefined",100);
replaceByType(level.enemies[i].follow,"number",level.enemies[level.enemies[i].follow]);

Sadly I don't know how to do this, because their is no way to pass a variable(other than an object) by reference. Maybe there is another way to simplify my code?

Marcin
  • 48,559
  • 18
  • 128
  • 201
Zelenova
  • 276
  • 3
  • 7

3 Answers3

1

I think you want something like this:

replaceIfAbsent(level.enemies[i], "life", 100);

function replaceIfAbsent(obj, property, newVal){
   if (typeof obj[property] === "undefined")
       obj[property] = newVal;
}

Or why not do multiple properties all at once:

function replaceIfAbsent(obj, properties){
   for (var prop in properties)
       if (typeof obj[prop.name] === "undefined")
           obj[prop.name] = prop.value;
}

replaceIfAbsent(level.enemies[i], [{name: "life", value: 100}, {name: "number", value: 12}]);

Are you using jQuery? If so, you can just do this:

$.extend(level.enemies[i], {"life": 100, "number": 12});
Adam Rackis
  • 82,527
  • 56
  • 270
  • 393
  • 1
    +1 for the jQuery.extend suggestion (which would have been my only suggestion ;-) -- other libraries, not just jQuery, provide a merge-capability. –  Jan 14 '12 at 23:03
0
Pass anonymous functions:

function replaceByType(test, pass, fail){
   if(test()) return pass;
   else return fail;
}

replaceByType(function(){return level.enemies[i].life},"undefined",100);

This defers evaluation until inside replaceByType.

Marcin
  • 48,559
  • 18
  • 128
  • 201
0

Since you can pass objects by reference, you can pass a property of the object that you want to replace.

function replaceByType(obj, property, type, value) {
   if(typeof obj[property] === type) {
     obj[property] = value;
   }
}

Which you can call almost how you were wanting to:

replaceByType(level.enemies[i], "life", "undefined", 100); 
replaceByType(level.enemies[i], "follow", "number", level.enemies[level.enemies[i].follow]); 
Peter Olson
  • 139,199
  • 49
  • 202
  • 242
  • Great! I have not thought about separating the object from its properties. We can even do `replaceByType(window,"variable","undefined",5);` to change a global variable! – Zelenova Jan 14 '12 at 23:23