
Advanced JavaScript Techniques - cwan
http://sixrevisions.com/javascript/6-advanced-javascript-techniques-you-should-know/
======
solutionyogi
Pardon me, but what's so advanced about these techniques? Anyone writing
JavaScript for living should already know these things. You want to talk
advanced? How about lazy function definition
[[http://peter.michaux.ca/articles/lazy-function-definition-
pa...](http://peter.michaux.ca/articles/lazy-function-definition-pattern)]? Or
say actual advanced JavaScript? <http://ejohn.org/apps/learn/>

~~~
slice
The lazy function technique can easily become an example of bad coding
practice. Code needs to be easy to read, understand, and maintain. In most
cases solution 2 is good enough, in all cases it's much simpler.

Advanced techniques should only be used when there is a clear justification to
sacrifice simplicity. It is disastrous when developers use so-called
"advanced" technique only to entertain themselves and show-off.

You are judged not by the niftyness of your code, but by the availability,
maintainability, stability and functionality of your system as a whole.

~~~
kls
Code needs to produce predictable results without bugs. All other qualities
are secondary. Good code without bugs is well encapsulated and should work as
a black box. Elegance is secondary to reliability. I am not saying that it is
not important, just not as important as reliability. As a general rule of
thumb less lines of code translates into higher reliability. I know it does
not apply to every case but it is a good starting point.

------
warfangle
I take issue with his object literal example for function arguments. My rule
of thumb is: if it's a required parameter, list it in the parameters. If it's
optional, put it in an object literal argument - but DOCUMENT it in a comment
at the head of the function. Using a lot of object literals as arguments can
get very hairy very quickly if you don't keep track of them, and keeps your
code from being self-documenting. By separating out your required and your
optional parameters, you can easily see which are which.

In his namespace example, also, he uses the new Object() notation, which is
not nearly as concise as var foo = {}, which does the same exact thing
(similarly, var arr = [] is better than var arr = new Array()).

We could rewrite the entire namespace initialization block as:

var MY = (MY) ? MY : { CUSTOM : {} };

This sets the variable MY to itself if it exists, otherwise assign an object
literal that has a member property CUSTOM that happens to be an empty object.
You could now create a new function, say, MY.CUSTOM.foo = function() {
alert('foo'); };

~~~
nkohari
I use this function to create namespaces:

    
    
      var namespace = function(ns) {
        var scope = window;
        var tokens = ns.split(".");
        for (var idx = 0, len = tokens.length; idx < len; idx++) {
          var token = tokens[idx];
          scope = scope[token] = scope[token] || {};
        }
      };
    

For example: namespace("Zen.Ui");

~~~
woadwarrior01
YAHOO.namespace in YUI does the same thing, except that it creates everything
under the YAHOO namespace.

------
tptacek
While nobody who's spent more than a couple weeks in jQ is going to learn
anything from this, I am at least thrilled to see that this isn't an article
about how to create animated dialog boxes and image carousels.

------
ramen
For-loops like "for (i=0;i<myLinkCollection.length;i++)" should always be
written like "for (var i=..."), unless there's an explicit "var i;"
declaration somewhere. Otherwise, this creates a global variable "i", which
can lead to some very confusing bugs if another function is called that also
references the global "i".

~~~
ams6110
But don't make the mistake of assuming that when writing "for (var i=...)"
that _i_ is scoped to the loop block. JavaScript does not have block scope. It
only has function scope, with the "Global Object" scope being the top level
scope.

~~~
maxwell
Only with JS <1.7. Otherwise you get block scope by using 'let instead of
'var.

~~~
tumult
Only SpiderMonkey (Gecko) has that. And it will remain that way for the
foreseeable future.

------
ed
Better namespacing:

    
    
      function _namespace(){};
      function _namespaceLib(){};
      
      // Define your library methods
      
      (function(){
        var _private;
        this.getPrivate = function(){return _private};
      }).apply(_namespaceLib);
      
      // Wrap your code with the new scope
      
      (function(){ with (_namespaceLib) {
        // Do anything you want here
        var local = "only visible in local scope";
        
        // The library is now in scope
        alert( this.getPrivate() );
        
        // Define your external methods
        _namespace.myAPIMethod = function(){return local};
      }}).apply({});
      
      // _private and local are not accessible
      
      _namespace.myAPIMethod(); // returns "only visible in local scope"

~~~
apu
I thought 'with' was generally frowned upon? Is it guaranteed to work
correctly in all situations?

And why is this a better namespacing method?

~~~
ed
Yes, "with":

\- adds an extra look-up when resolving scope

\- creates code that sometimes isn't immediately obvious

But with this technique you basically get to forget you're writing code in a
namespace. You can var myFunc; all you want without polluting the global. And
you can put the library in a separate file and reference its exposed methods
as if they were written in the body of your application.

------
pmichaud
Number 6 is terrible -- hacking together html from strings is just not the
right away to do it. He should be generating the DOM elements and
appending/nesting the generated elements appropriately, not concatenating a
messy string.

~~~
willwagner
Unfortunately, if you are adding a lot of elements, your performance can
really suffer by creating DOM elements. It helps if you
"createDocumentFragment" but as far as I know, shoving a big string into the
non-standard innerHTML member is still the fasted way to add a lot of content.

~~~
axod
That's true for IE, but not for good browsers. For firefox/safari/chrome it's
negligable difference if not sometimes slightly faster to use the DOM methods.

Also, using DOM methods allows you to easier attach listeners, save references
to DOM elements for later updates/use etc. That means less getElementById()'s
later.

Writing HTML inside js code is just horrible (IMHO). Horrible ugly code. And
obviously easier to have security issues if you're including non-sanitized
user data.

#6 is a horrible idea.

As far as your JS code is concerned, HTML is a (horrible, ugly) serialization
of the DOM. Manipulate the DOM programatically. Don't use HTML.

~~~
jedediah
Sadly, most of us have to code for IE, just as we have to code for the "good
browsers".

~~~
axod
If you're in the 'webapp' area, where IE is a minority (20% or so), I think
it's justifiable to program in a clean way and live with IE users having a
slower experience.

innerHTML is just the worst thing ever invented. Ugly ugly thing.

~~~
JeffJenkins
Where does that 20% stat come from?

------
ams6110
Best eye-opener I had on JavaScript is Douglas Crockford's site.
www.crockford.com. Many folks here probably know of it, but if you've never
perused that site you're missing something good.

~~~
samuraicatpizza
Crockford is awesome. Here's one of my favorite pieces he wrote on his jslint
javascript parser (written in javascript):
<http://javascript.crockford.com/tdop/tdop.html>

------
davt
And agreed, the 6 techniques are not that good. If your going for speed, dont
expect ppl to read your code. It wont be readable. Animations are processor
dependent and the code should be streamlined as possible to make it fast FOR
THE PROCESSOR. It won't look like your average JS. It's a re-factor dance for
me everytime. Like tuning a car, certain things work better for tuning
Ferarris than they do for a Cadillac. (I don't have either) :) MOST IMPORTANT
LEARN MATH!!! you now need all that calculous and trigg and geometry. You need
matrices, you need x,y,z mapping. I need everything I thought I would never
need...and more. Still learning

------
moron4hire
I love JavaScript as a language, there are some neat things in it (not the
least of which is expando object, whoo), but there are much better tools than
it for doing application development (even if we go no further than Flex or
SilverLight, we've improved dramatically over JavaScript in terms of project
management and toolchain availability). If you're worried about namespacing,
then you're using the language with the intention of a real application
programming language. There are other ways to get code to client in a web-
accessible way that doesn't mean "AJAX everywhere!"

------
davt
you guys should really check out:
[http://www.webreference.com/programming/optimize/speedup/cha...](http://www.webreference.com/programming/optimize/speedup/chap10/1/index.html)

I have been creating some pretty crazy interfaces in 3D Javascript. I try
everything I read to see if its faster. I find that its resizing elements
during an animation that really affect speed. Stopping event bubbling is
pretty nice too. But things I didn't know like using reverse loops because
comparing to "0" is faster than an int. or setting [i] into variable after the
"++" so the whole length isnt processed over and over. What about using
"Math." instead of (var calc = a1 * a2 / a3), var calc =
Math.round((a1*a2)/a3); because using the preMthods in the dom is faster.
These things really work and I saw my performance shoot through the roof!! My
number one performance enhancer though? Dont use <img> tags. The way the
browsers render <img> is different than (backgroun-image:url();) and takes
much more out of the speed than using a CSS background.

------
davt
Also, if your using trigg based JS, having good math is important. A lot of
the time if you can shorten your math into more elegant equations, you will
see serious performance gains. Of course I sucked at math, still do, but I'm
getting better. I now run a base set of equations and just manipulate the base
equations when needed.

------
woadwarrior01
Regarding #6, Isn't it a better idea to do something like

['<h1>',text,'</h2>'].join('')

instead of

'<h1>'+text+'<h2>'

Something like the latter is generally frowned upon in Python because it
increases the number of temporary objects that have to be allocated, I'm sure
the same logic holds good for most if not all Javascript implementations as
well.

~~~
gord
Are there any js frameworks/libs that do something like this on the client :

    
    
        render_as_dom(table(tr(td("one"), td("two"))));
    

I'd prefer to write code like this rather than have a mix of JS and html, with
html rendering on the server.

~~~
tlrobinson
[http://www.nonblocking.io/2009/09/dsl-for-generating-html-
wi...](http://www.nonblocking.io/2009/09/dsl-for-generating-html-with-js.html)

~~~
gord
Thanks,

which led me to this -

<http://www.cactusjs.com/browser/trunk/DOM/tag.js>

which is basically a js version of what Ive been doing in PHP with xilla tags.

Given they've implemented both 280Atlas [Obj-J on js] and Suns Lively Kernel
in Javascript, there must be a way to avoid HTML generation and even code
server and browser side in a similar looking pseudo-lisp dialect...

~~~
tlrobinson
(I'm 1/3 of 280 North, btw)

In Cappuccino each "view" object (CPView, CPButton, etc) has a DIV element as
it's base, and other elements contained in that (usually just IMG, canvas/VML,
or subviews' DIVs). We don't output HTML at all, but rather manipulate the DOM
elements at runtime.

This sort of approach definitely makes sense for the kind of highly
interactive _applications_ Cappuccino is designed for, but maybe not for more
"pagey" _websites_ where you want search engines to be able to index it, etc.

~~~
gord
absolutely.. [Greets + Kudos, btw]

But then so many 'web pages' now are really js apps, that google must
effectively do screen scraping anyway... Perhaps we should just admit that we
always need an alternate feed to provide semantic meaning [aka tags] to web
crawlers/readers, and be done with it.

Maybe a system where each widget can be queried for its textual content, via a
standard simple API would mean all apps made with say Cappucino would be able
to emit text to a crawler, without [too much] special code being written - the
framework could do it?

Running a JS program on the browser to generate the page should be a legit
technique, even for pages that remain static thereafter.

Have you had a look at RaphaelJS? [normalized SVG support via JS : allows JS
to do flash-style animations with an open standard behind it].

------
dmoney
I don't understand #5. Using a library makes something a "Hybrid Application"?

------
davt
here is another really good one:
<http://home.earthlink.net/~kendrasg/info/js_opt/>

