Search code examples
javascriptjsonperformanceclosuresmemory-efficient

Best way to set up function in Javascript (likely via closure?)


I've got a web application that makes a call to a web service which returns some JSON representing an array of objects. Each object has some fields. Here's some example JSON to give an idea:

{
   "data": [
      {
         "id": "12345",
         "from": {
            "name": "John Doe",
            "id": "6789"
         },
         "start_time": "2012-12-16T02:17:20+0000",
         "end_time": "2012-12-16T02:17:20+0000",
         "publish_time": "2012-12-16T02:17:20+0000"
         }
      },
      {
         "id": "8888",
         "from": {
            "name": "Jane Smith",
            "id": "011"
         },
         "start_time": "2012-12-16T02:17:20+0000",
         "end_time": "2012-12-17T02:17:20+0000",
         "publish_time": "2012-12-16T02:17:20+0000"
         }
      }
   ]
  }

Once this comes back, I use jQuery's parseJSON() method to inflate this into an array of objects (holding onto the "data" value). That's all fine, but after I have my array, I have several functions that can operate on each array slot. For example, let's say there's a function called GetDuration() that will print out the time lapse between end_time and start_time. In any case, I define several functions (maybe 15) and at this point, I simply iterate through the entire array and inflate every object with a copy of the function. Example

for (var i=0;i<data.length;i++)
 data[i].TimeLapse = function() { ... };

I think this can be made much more efficient. Right now, I think there's a separate copy of the same function for every array item, which is not necessary. I've also noticed a lag in the processing time, which I'm hoping can be reduced. I've read about javascript closures which seem like they could help me in this circumstance, but I don't have much experience writing functions in closures. Would I set up the closure and then modify the JSON to somehow inflate to the closure typed object? Or would I inflate to the regular javascript objects like I'm doing today and somehow go through and change the object type to point to a closure I've created?

Any thoughts or suggestions would be appreciated.

Thanks...

-Ben


Solution

  • As others have written in comments, it's not clear what you want, but this sounds closest to what you're describing:

    function make_duration_fun(x) {
        return function() { return GetDuration(x.start_time, x.end_time); };
    }
    

    Then your loop can do:

    data[i].TimeLapse = make_duration_fun(data[i]);
    

    There's just one duration function, but each time you call make_duration_fun you get a new closure with that same function and different x binding.