JavaScript Idioms Every Webdev Should Grok

JavaScript (the language, not the browser bindings for the DOM, etc.) can be either brutally hard or refreshingly flexible. It’s difficulty is directly related to how well you grok a couple of core concepts. I’m going to just list them and leave in-depth explanations to Tom’s forthcoming book on advanced JavaScript.

Here goes:

  • Everything in JavaScript is an Object. Even functions
  • Every object is always mutable
  • The dot operator is equivalent to de-referencing by hash (e.g., foo.bar === foo["bar"])
  • The new keyword creates an object that class constructors run inside of, thereby imprinting them
  • Functions are always closures (combine w/ previous rule to create OOP)
  • The this keyword is relative to the execution context, not the declaration context
  • The prototype property is mutable

If all of that makes sense to you, JavaScript can be a fun, liberating experience. If not, it’s going to be a world of pain and broken expectations as you shed the baggage of less dynamic languages.

Good luck.

26 Comments

  1. Posted January 18, 2006 at 1:13 pm | Permalink

    This makes me want to read more ;) Any details on Title/Publisher?

    greets, alex

  2. Venu Reddy
    Posted January 19, 2006 at 7:45 am | Permalink

    Would love to learn more about it instead of just doing the copy/paste/tweak routine.

  3. Posted January 19, 2006 at 9:10 am | Permalink

    And what *is* Tom’s upcoming book?

    You don’t say it’s title or even his last name (I had to go digging through his f(m) project site to track down “Thomas R. Trenka” and there is nothing on Amazon under his name).

    This is not terribly helpful for people who do want to learn more (for example, I don’t quite grok the “thereby imprinting them” bit).

    I’m not asking for a transcript of the upcoming book, but please flesh this post out, if you can. It would be greatly appreciated by people like me who want to stay on top of things instead of just hearing how they’re losers.

  4. Posted January 19, 2006 at 10:13 am | Permalink

    Joe, I don’t know if Tom’s book even has a title yet. Needless to say, it’s going to be on advanced JavaScript (aka: JavaScript for “real programmers”). Once I know more about what he and the publisher have worked out, including title, I’ll post it.

  5. Jeremy Dunck
    Posted January 19, 2006 at 10:22 am | Permalink

    Nice list, but, uh, these aren’t idioms, they’re facts about the language design. ;)

  6. Jeremy Dunck
    Posted January 19, 2006 at 10:32 am | Permalink

    Joe, “thereby imprinting them” means that within a constructor (which is just a function called after using the “new” keyword), the “this” keyword refers to the newly created object.

    function Foo() {
    this.x = 1;

    this.gimme = function() {
    return this.x + 1;
    }
    }

    y = new Foo();

    assert(y.x == 1);

    Moreover, you can fake class-based inheritance with:

    foo.prototype=BaseClass();
    foo.prototype.constructor = foo;

    What that does is place all the attributes of the BaseClass class instance on the prototype of Foo. This means that when an attribute lookup fails on a Foo instance, it will then try looking up against the BaseClass attributes (which are on the prototype). This looks a lot like class inheritance if you squint right (and remember that “this” is squirrelly, which Alex also points out).

    A problem comes in when you try to hook up an “instance method” of Foo to do something in an event handler.

    y = new Foo();
    assert(y.gimme() == 2);

    But:
    button.onclick = “alert(y.gimme())” will error rather than alerting “2”, because in an event handler, “this” refers to the elm which sourced the event.

    This is why Function.prototype.apply exists, and why Aaron wrote a “hitch” function a while back. It’s useful for making sure “this” means what you would expect it to mean.

  7. Posted January 19, 2006 at 10:38 am | Permalink

    Jeremy: great clarifications. Thanks.

    Joe: as Jeremy mentions, Aaron Boodman’s hitch() function (which is now part of dojo.lang) is useful in ensuring that things are local to the scope you bind them to, but it can have some significantly sub-optimal consequences when used inside of inheritance structures. I recommend you only use it on instances of classes and not as a way to bind every method on a class to that class exclusively (say, in the constructor).

    Regards

  8. Bog
    Posted January 19, 2006 at 1:07 pm | Permalink

    What the fuck does grok mean?

  9. Posted January 19, 2006 at 1:10 pm | Permalink

    Bog: http://www.jargon.net/jargonfile/g/grok.html

  10. Posted January 20, 2006 at 2:54 pm | Permalink

    I have a question about: The this keyword is relative to the execution context, not the declaration context

    If I have a window A that opens window B (thereby creating a linked execution context through B’s opener property), how can I call new on classes declared in A?

    In other words, if A declares class Foo = function() { }, how can B instantiate Foo objects? From B, I can call new opener.Foo(), but it doesn’t work in IE 6.

    Or, if I declare Foo() in B as well as A, how can I pass Foo instances from B to A and have them still work after B is closed?

    BTW, when you have a chance, check out http://www.jsorb.org.

  11. Posted January 20, 2006 at 5:19 pm | Permalink

    Brad,
    This is not what Alex was referring to when talking about execution context. What he’s referring to is the use of the “this” keyword during the execution of a function. You’ll notice that if you have, say, a function to handle a generic click event, and you use “this” to refer to the element that fires the event, like so:function eh(e){
    alert(this.id);
    }
    var nodes=document.body.getElementsByTagName("div");
    for(var i=0; i
    You'll notice that every time that event fires, "this" refers to the element that fired it, i.e. the execution context.

    What you're referring to there are sandbox/global objects, and no, with IE you cannot transfer things by reference between windows. You *can* create new objects in the other window though, but there's a number of caveats about it.

  12. Posted January 20, 2006 at 8:56 pm | Permalink

    Thanks for the reply. I already grok the this context stuff, and all the joys that it inspires. I figured I might need to perform some magic to get my objects across the window boundary, and fortunately I have a full marshaller/unmarshaller at my disposal: JsOrb. (http://www.jsorb.org/)

    JsOrb gives you full access to your Java POJOs and interfaces from the browser. It can marshall a full graph of objects over HTTP, and invoke methods on your J2EE server. Basically it gives you a JS API that looks almost exactly like your Java API, and takes care of all the AJAX work for you.

    The same marshalling JsOrb uses for getting objects to/from the application server can be used to transfer a graph from one window to another. I just need an API, a list of invocations, and a mechanism to poll the list in each window. Shouldn’t take too long.

  13. Foo Bar
    Posted January 23, 2006 at 3:17 pm | Permalink

    please please please STOP saying “grok”.

  14. Posted January 23, 2006 at 5:58 pm | Permalink

    grok.

    grok grok grok.

    grok grok.

    grok.

    (I love anonymous commenting)

  15. Geek
    Posted January 24, 2006 at 10:39 am | Permalink

    Sure, we could say “understand” instead of “grok,” but grok implies a deeper, fully internalized understanding of a concept. The English language has a very large (compared to most languages) vocabulary. I, for one, prefer to use the word that best conveys my exact, subtle meaning. There is no need to use imprecise Orwellian new-speak when there is a double-plus-good word like grok at your disposal.

  16. Posted January 24, 2006 at 10:42 am | Permalink

    Well, I’m glad we’re continuing the discussion of the salient points of the post and not the offhand title I slapped together as an afterthought.

    *sigh*

  17. Posted January 25, 2006 at 12:05 pm | Permalink

    As an aside to the grokking, I got my code in to move graphs from one JS context to another. It was fairly easy (given that I had a marshaler handy), but the IPC (IWC?) was a bit complicated due to JS not having wait..notify support a la Java and other languages.

    I needed to write polling “threads” (interval functions) to handle the request/response nature of this type of activity. But it works fine. You call JsOrb.importGraph(context, obj, callback) and your callback is executed when the import is complete, and gets passed a reference to the imported graph.

    Yet another reason to hate IE: why not let me instantiate objects in another JS context?

  18. Posted January 25, 2006 at 7:16 pm | Permalink

    Thanks for the more thorough explanation. Now I have something to contemplate and play around with instead of just feeling like I’m retarded. :)

    Anyhow, I like “grok” … “understand” seems insufficient. I guess my analogy would be that you can read all the automotive magazines you wand, but until you get behind the wheel of a car, you don’t “grok” driving.

  19. Posted January 26, 2006 at 3:04 pm | Permalink

    Just a couple of clarifications:

    Every object is always mutable

    Except numbers and strings and functions and perhaps a few other things.

    The dot operator is equivalent to de-referencing by hash (e.g., foo.bar === foo[“bar”])

    Not quite equivalent. You can say foo[‘string with spaces’] and foo[‘keyword’] (where keyword is a Javascript keyword, like “for.” Neither of these cases work using dot notation.

    I don’t think either of these points detract from what you’re trying to say, but I’ll make them in the interest of accuracy.

  20. Posted January 26, 2006 at 3:19 pm | Permalink

    Hi Dethe,

    My statement about objects (variables whose .constructor property in some way descends from Object) was correct. Primitive string *values* are immutable in JS, but an object of type String may have new properties added to it at any time. Same with object of type Number. Their primitive values, however, are (as you point out) immutable.

    Also, the hash deference is exactly equivalent. That there’s no way to have a JS lexer handle an variable name with spaces in it in no way detracts from the equivalence, it just means that the dot operator has to follow the rules of thing that aren’t string literals. Also, note that the way it was phrased, I said that anything you can do with the dot operator you can do with hash dereferences. I didn’t say it worked the other way around.

    Regards

  21. Posted January 26, 2006 at 3:39 pm | Permalink

    Hi Alex,

    Good points, and clearly made.

    Sorry about missing the closing blockquote in my earlier response, I’ve gotten used to comment previews, I guess.

    –Dethe

  22. Posted January 26, 2006 at 4:07 pm | Permalink

    In response to Jeremy’s comment about this, I’d like to point out that his demo is incorrect. Calling y.gimme() in an event handler should work because you it will see the ‘y’ and know to assign the proper ‘this’. If, on the other hand, you did:

    x = y.gimme; x();

    You’ll get NaN because it doesn’t know to setup the correct scope.

  23. Posted January 26, 2006 at 4:23 pm | Permalink

    One other thing about identifiers…ECMAScript v3 allows for escaped Unicode characters as part of the identifier (as long as it satisfies the other rules of an identifier). For instance:

    var business\u0032business=”bar”;

    …is perfectly legal, even though you’ll probably want to use “2”.

  24. Jeremy Dunck
    Posted January 27, 2006 at 4:31 pm | Permalink

    David is right, of course. That’s what I get for tossing off an example without coding it. :(

  25. Posted March 2, 2006 at 4:17 pm | Permalink

    Hello Alex,

    For a new user of JavaScript what would be a good start to grok the core concepts? A book/tutorial will be helpful.

  26. SmalltownJava
    Posted May 3, 2006 at 6:40 am | Permalink

    Great discussiion!

    A few notes regarding object access and windowing…

    I’m not familiar with using jsOrb as a library, but I do know that you can pass dynamic objects such as Datasets from the parent window to the child and vice versa using simple object reference.

    Additionally, you also use that methodology to notify child/parent asynchronously when processing large objects, script requests via XMLHttpRequest and dynamic script src execution requests. That is very useful when building web applications and is fundamental to AJAX.

    As a language, Javascript is very robust but only to the extent of thought put into its application.

7 Trackbacks

  1. By Ajaxian » JavaScript idioms you need to know on January 18, 2006 at 9:05 pm

    […] Alex Russel (of Dojo fame) has a nice post on fundamental principles of JavaScript you need to really grok the language. Once you understand them, you’ll be well on your way to creating real JavaScript instead of just doing the copy/paste/tweak routine. The key points are: […]

  2. By Ajaxian on January 18, 2006 at 9:07 pm

    JavaScript idioms you need to know

    Alex Russel (of Dojo fame) has a nice post on fundamental principles of JavaScript you need to really grok the language. Once you understand them, you’ll be well on your way to creating real JavaScript instead of just doing the copy/paste/twea…

  3. By Argan’s blog » JavaScript idioms you need to know on January 18, 2006 at 10:06 pm

    […] ?自 http://alex.dojotoolkit.org/?p=535 […]

  4. […] Alex Russell (lead developer for dojo) has posted a list of “JavaScript Idioms Every Webdev Should Grok“. If you understand them all then you’ll love coding in JavaScript. The more that baffle and confuse, the harder and more painful you’ll find developing with JavaScript. […]

  5. By Project :: penkiblog » 本日書籤 on January 19, 2006 at 2:23 pm

    […] http://alex.dojotoolkit.org/?p=535 […]

  6. […] Dojo’s Alex Russel has a good post on the fundamentals of JavaScript here. There is a big difference between being able to get by in JavaScript and being able to really work with it. […]

  7. […] JavaScript Idioms Every Webdev Should Grok 一些 javascript 的 語言?點 […]