1
\$\begingroup\$

Say I have this type of code I'd like to execute. There's some data encapsulated around a big Javascript object containing methods & properties that I'd like to extract based on comparing some other data in said object. The object includes associative (hash?) arrays where I don't know the array IDs at runtime so I have to do some iteration, this is the working code structure I came up with. But it's bloated and a bit messy to read. Was wondering it it can be optimized for efficiency and readability in general, to minimize iteration and conside the length of the object referencing.

I execute this code from Firebug console (or via Selenium WebDriver's execute javascript command, in which case console.log become "return" to return the desired value).

for(x in MainObj.aaa.bbb[MainObj.someGetIdMethod()].someObjArry){
    if (MainObj.aaa.bbb[MainObj.someGetIdMethod()].someObjArry[x].someObj.displayName == 'some value')
        console.log(MainObj.aaa.bbb[MainObj.someGetIdMethod()].someObjArry[x].someObj.someId);
}
\$\endgroup\$
4
\$\begingroup\$
  1. You should cache all methods calls - JS is interpreting language and there is no optimizers to help you, therefore, each time you call method, get element from array etc, you are actually asking JS engine to DO this for you.
  2. Concluding that someObjArry is an array, should avoid using loops with "in" statements - use standard loops with indexes instead. "in" statement walks through all object's properties, not collection's elements, so it's just future maintenance "watch-out".
  3. Property "displayName" of object "someObj" seems like of a string type - try using strong type comparisons if possible (not an optimization, just a good practice)
  4. Cache as much as you can

var someArray = MainObj.aaa.bbb[MainObj.someGetIdMethod()].someObjArry, 
    arrayElement;

for(var i=0, $length = someArray.length; i< $length; i++){
    arrayElement = someArray[i].someObj;

    if (arrayElement.displayName === 'some value'){
        console.log(arrayElement.someId);
    }
}
\$\endgroup\$
  • 2
    \$\begingroup\$ I'd love to see a demonstration in modern browsers where pre-grabbing the array length is a performance enhancing measure. Even if it does save some time, it adds quite a bit of noise. I'll grant that there may be some things returned by DOM functions (like getElementsByTagName) which return array "like" objects, and grabbing the length might make sense on them. Of course, there is also the native forEach which might prove faster (but not all browsers support it). And finally, JavaScript is generally compiled these days, but it is a good idea to use someArray as suggested. \$\endgroup\$ – JayC Feb 21 '13 at 4:19
  • 1
    \$\begingroup\$ @JayC also languages like CoffeeScript will do the all the caching (both the someArray and the $length) automatically when compiling to JavaScript, making the code somewhat cleaner without having to do these things (and also variable declarations) manually. \$\endgroup\$ – Attila O. Feb 21 '13 at 11:09
  • \$\begingroup\$ Thanks, I was lazy to break out the code with variable assignments. The suggested code is cleaner to read. I guess that's about as optimal as you can get with the code though? \$\endgroup\$ – David Feb 21 '13 at 18:37
  • \$\begingroup\$ @JayC take a look at jsperf.com - plenty of tests of this sort of stuff. And you can make your own :) \$\endgroup\$ – Flambino Feb 21 '13 at 19:40
  • \$\begingroup\$ @Flambino: Actually, I was kinda hoping Arthur P already had such a test or knew of such a test there. But the fact that a CoffeeScript compiles (math.cube num for num in list) to a for loop set up like Arthur's is rather convincing to me that there probably is something to caching the length and this observation also makes me reconsider if I shouldn't regularly be using some language that compiles to JavaScript or not. \$\endgroup\$ – JayC Feb 21 '13 at 23:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.