Infrequently Noted

Alex Russell on browsers, standards, and the process of progress.

Comments for JavaScript Idioms Every Webdev Should Grok


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

greets, alex

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...

by Ajaxian at
Would love to learn more about it instead of just doing the copy/paste/tweak routine.
by Venu Reddy at
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.

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.
by alex at
Nice list, but, uh, these aren't idioms, they're facts about the language design. ;)
by Jeremy Dunck at
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.

by Jeremy Dunck at
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

by alex at
What the fuck does grok mean?
by Bog at
by alex at
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.

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.

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.

please please please STOP saying "grok".
by Foo Bar at
grok.

grok grok grok.

grok grok.

grok.

(I love anonymous commenting)

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.
by Geek at
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

by alex at
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?

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.

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

by alex at
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.

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

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.

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".

David is right, of course. That's what I get for tossing off an example without coding it. :(
by Jeremy Dunck at
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.

by Asfaw at
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.

by SmalltownJava at