2 Javascript discoveries

If you are an experienced Javascript developer, the following will not come as a surprise to you, but for those who might be struggling with some of the quirks of this otherwise pretty useful language, I’d like to share 2 discoveries. I spent quite some time trying to understand why certain code wouldn’t do what I intended and after several frustrating hours, I finally found that

  • Javascript is not a pure “pass-by-value” language, as I thought. When passing an object to a function, any changes to the internals of that object within the function, will alter the object outside the function.
  • A long-running JavaScript will freeze the browser, preventing it from being updated, so any visual changes will not be visible, until after the processing has finished.
    • Solution: Add a delay (even a 0ms delay) between making a visible change, and starting the script. Add this delay using setTimeout():
      $("#xxx").addClass("changing");
      setTimeout(function () {
      // process long scripts
      }, 0);
      

Background:

  • Some complex code on one of my websites didn’t behave properly, even though the code looked fine. Eventually I learned that an object that I passed to a function should not be altered within that function, as it directly changes the object itself, rather than a copy, which would be the case in a pure “pass-by-value” language. See http://nsono.net/javascript-pass-by-value-or-pass-by-reference/ for details.
  • I’m using the powerful datatables plugin on my websites. As some tables contain a lot of columns, I wanted to provide shortcuts to dynamically show or hide certain columns. You can do that with the column().visible() method, but as the table is large, it takes a few seconds to see the result. I therefore wanted to show the user that some processing was going on, with a small popup or by adding a “changing” class to a DOM element. However, these visual changes did not show, or better, they only showed AFTER the processing was done. I really didn’t understand why it was not working, until eventually http://stackoverflow.com/questions/20048357/loading-overlay-with-datatables gave a clue: “A long-running JavaScript will freeze the browser, preventing it from being updated.” Using setTimeout() with a delay of 0ms finally solved it.