Skip directly to content

Why so many of us hate JavaScript

on October 18, 2010 - 6:31pm

I know some really smart Drupal developers who hate JavaScript. Maybe you're one of them. Here's a little quiz: You read in the Drupal 7 module upgrade guide that all D7 JavaScript code should be wrapped as follows:

(function ($) {
  // Original JavaScript code goes here 
})(jQuery);

What is your reaction?

a) Nice! A self-executing function that's closed over the free variable $ at execution time.
b) Oh right, that clever-looking jQuery pattern that I've seen all over but don't understand because I can't Google it.
c) What the freak is that? I guess I'll copy and paste it even though it makes no sense. I hate JavaScript.

If you answered c), you're in really good company. I gave a talk called "JavaScript Demystified" at the Pacific Northwest Drupal Summit in Vancouver a couple of weeks ago, where I talked about why JavaScript is so confusing to PHP developers, and how we can write it differently. There's more to talk about than I could fit in one hour, so I'm starting a mini-blog on this site where I can blather at length.

During the talk (slides available here), I spent most of the hour fulminating against closures. Wikipedia helpfully informs us that a closure is "a first-class function with free variables that are bound in the lexical environment." That is total gibberish to people who haven't studied functional programming. In case you're in that category, here's a quick explanation: functional programming is what you do when you're writing Lisp, or Erlang, or Haskell. In these languages, the functions you write are just like the mathematical functions you studied in algebra class - all that ƒ(x) = 2x business. It's a totally different way of programming, with its own set of tradeoffs, which Larry Garfield explained really well in a recent blog post that I recommend to anyone who wishes they'd taken CS in college.

One reason JavaScript is so confusing is that you can write it in a functional style, using closures. In fact, most of the JavaScript you'll find in the wild is full of closures. Here's an example of one:

Drupal.behaviors.myModule.attach = function (context, settings) {
  // This is a simplified example, so Drupal experts, please overlook the blatant omission of $.once and context.

  var message, hideMessage;

  // Find where the message is on the page.
  message = $('div.messages');

  // Define a function for hiding the message.
  hideMessage = function () {
    message.css('display', 'none'); // <-- We just used a variable we didn't define inside our function!
  };

  // Hide the message (in real life, we wouldn't call this until someone hit the close button, or whatever).
  hideMessage();
};

See how the message variable was defined outside the hideMessage() function? That's what makes hideMessage() a closure: it uses a variable that got defined in its parent function. And if you're going in to fix a bug in hideMessage(), you have to know all about the message variable: where was it defined? What is its value when hideMessage() gets called? Is there code further down the page that sets message = $('#some-other-div-entirely')?

This is a really simple example, so it's not hard to follow what's going on. But add in a whole bunch more variables, and start writing functions within functions within functions that use variables defined in their parent function and their grandparent function, and unless you're an experienced functional programmer, you have the recipe for a big pile of spaghetti code. Even worse, it's spaghetti code that you can't understand unless you know what closures are and how they work.

The good news is that you don't have to learn Lisp to write good JavaScript. There are ways to avoid writing closures, and to limit the scope of the closures you absolutely have to write, so that people can understand your code even if they don't write JavaScript books for a living. The example code from my presentation demonstrates some of the ways you can do that, and I'll expand on those examples in a future post if anyone's interested.

By the way, my answer to the quiz question is

d) Don't bother wrapping your JavaScript in that crazy closure at all. Just stick var $ = jQuery; at the top of any function where you want to use $. Life is too short.

Comments

James O&#039;Beirne's picture

If you find closures or anonymous functions opaque, maybe you shouldn't be getting paid to write JavaScript. Honestly, which is better for readability? It should take about fifteen seconds to explain/understand self-executing, anonymous functions used for scoping.

investasi lahan sawit's picture

Fatty Acid Other benefits associated with palm oil producers since it was established in 2004.
Most poor people are in palm oil 2009 the air because of this
trade. The oil is also the center of the dish here, then we take a little
bit of our lemon olive oil, coconut oil and palm kernel oil.
The story was followed closely by palm oil 2009 specialist media, such as soya,
sugar, cotton, seafood and beef.

Terrence's picture

Does your blog have a contact page? I'm having trouble locating it but, I'd
like to send you an e-mail. I've got some ideas for
your blog you might be interested in hearing. Either way, great
site and I look forward to seeing it expand over time.

Local Seo's picture

This article will help the internet people for creating new website or even a
weblog from start to end.

BiGadgets's picture

Hello.This ρost ωas extre&X6D;el&X79;
fascinating, pаrtіcularly because I was browѕing &X66;oг thoughts on thіs s&X75;bje&X63;t
las&X74; Mondаy.

Provider pulsa Termurah's picture

Our operating expenses, last year we had a record quarter in terms of
business interruption insurance, we have not monetized our towers.

So we've managed to drive gross margins up. Therefore, the costs involved are
now minimal or close to zero. Bob can you explain or remind us daftar distributor pulsa your relationship with Juniper, I think, and
I don't know that it's going to be able
to expand with you.

trader's picture

There's definately a great deal to know about this topic.
I like all the points you have made.

broer/zuskado's picture

of course like your website but you have to check the spelling on quite a few of your posts.
Several of them are rife with spelling problems and I
to find it very troublesome to inform the truth then again I will certainly come back again.

royalty free images's picture

Very good article! We will be linking to this great article on our website.
Keep up the good writing.

amoxicillin's picture

With havin so much written content do you ever run
into any issues of plagorism or copyright infringement? My blog has
a lot of unique content I've either authored myself or outsourced but
it looks like a lot of it is popping it up all over the internet without my authorization.
Do you know any ways to help stop content from being ripped off?
I'd certainly appreciate it.

Lignes automatiques Pellets Ease's picture

If you desire to get a great deal from this post
then you have to apply these strategies to your won web site.

Josh Caldwell's picture

By placing $ = jQuery at the top of your function you're actually creating a situation where window.$ = jQuery ... (var $ = jQuery; would work) ... additionally, part of the point is to create a closure in which the functions that you define, variables, ect, will not conflict with other modules functions and variables, you're bypassing that ... and thus defeating the whole purpose and causing possibly namespacing issues.

accident claims solicitors's picture

You can certаiny see уour expertise in the work you write.
Thee arena hopes foг more paѕsionate writers such as you who aren't afraid
to mention how they believe. Αll the time follow your heart.

visit the up coming article's picture

I visited several blogs but the audio feature for audio songs present at this web
page is actually superb.

when do you do up grades on your home's picture

Hello! Do you know if they make any plugins to protect against hackers?
I'm kinda paranoid about losing everything I've worked hard on.
Any suggestions?

Erik Reppen's picture

You've misunderstood the one up top. It's just a lazy way to define an anonymous function and fire it while avoiding pollution of the global namespace.

function(){}//a completely useless function definition
var x = function(){}; x();//assigned to a var (causing evaluation) and fired

function(){}(); //but you can't just fire it like that. It's not evaluated
//until after that statement is closed (the semi).

These work because the operators force evaluation of the funcs:
+function(){ alert('bob'); }()
!function(){ alert('bob'); }()

Paren style is generally preferred because forgetting a semi could cause something extra-stupid to happen in the above examples and parens are commonly used to force evaluation.

So, what you have up top there:

function($){} //a function definition defining $ as a parameter name

(function($){})(jQuery);
// that func defined, evaluated with parens, and fired with jQuery passed in to
//the $ param - it's just a lazy way to do it all in a one-liner

The whole point by the way is to assign jQuery to a local context of the function so you're not bouncing up and down the call object chain every time you reference jQuery. They also use this in the JQ factory definition to bring window down to a local reference so it can be minimized.

People tend to confuse what I call anonymous auto-invoking functions (self-invoking is a bit of a misnomer) with closures because they are frequently used in examples of how to resolve closure issues. A good example of a closure shows a var's value getting locked into place because what closures really are is the binding of execution context to function definition as the function scope closes.

//the problem - all these funcs alert 0
//Why? Because you call that func when the loop is done and i is 0 at that point
var i = 8,
arrayOFuncs = [];
while(i--){
arrayOFuncs[i] = function(){ alert(i); }
}

//The solution - lock execution context down by completing a function call.
//Scope closes but the func holds the var value as it was when the scope closed.

var i = 8,
arrayOFuncs = [];
while(i--){
//function defines and completes - i would be out of scope without closures
arrayOfFuncs[i] = (function(){
return function(){ alert(i); }
})()
}

//Now you should get different vals for each array element func fired
//e.g arrayOfFuncs[3]; //'3'

It has taken me a few 'aha!'s to get here. So let me re-describe. If a language does not have closures, when a function is done, everything inside is tossed out, garbage-collected, meaningless. Without closures, you cannot have very interesting first-class functions (funcs passed as params). But the important thing to understand above:

In the all-alerts are '0' example, you can still see i because of JS-scoping. It's okay for JS funcs to see what's in outer-contexts. This may be closure-related actually but I'm not going to pretend I fully grok that.

In the all alerts are <i at time of definition> example, 'i' is locked down because the outer function finished, tried to garbage collect but saw that a function that could be fired by anything else later was referencing 'i'. So that func gets to have a local var 'i' to reference that is locked down at the value of the outer-i that the outer function "closed" on. The concept of "closure" is execution context getting locked down when we find a way to make it possible for vars inside a function to be referenced after it's supposedly finished doing what it was doing.

Don't feel bad, I've had guys at a Netflix interview tell me (function(){})() is a closure. It's not, really. Evidence of closures being likely, yes. But not a good example of a closure.

Also, free yourself from Drupal. Trust me on this one.

escort napoli's picture

Oh my goodness! Impressive article dude! Thank you, However I am going
through troubles with your RSS. I don't understand the
reason why I can't join it. Is there anybody else having similar RSS issues?
Anybody who knows the solution will you kindly respond?
Thanks!!

Jason's picture

Why are most Javascript code snippets displayed in black and white on most articles that you come across? This enhances the view that javascript is ugly as without colour coding your mind needs to exert extra effort to separate the various blocks and meanings. Any other language and its usually grey for comments, blue or black for language statements and green for strings, but Javascript seems to be predominantly written using notepad, or at least most of the code listings you come across seem to be like this. I think if you use a proper editor to write Javascript, it becomes a lot more easier to follow the code and bring it more on level with other programming languages.

biomass's picture

The rеsult is basісally an inexhаuѕtіble sоurce of
free pοwеr thаt ԁoеs nоt pollute the еnvігonment or еmit gгeen house gasеs.
Alott oof our children probably ωill not
bе toо pгoud with all theiг anceѕtors if ωe don't dο аnуthing at
all bеnefiсial wіth refегence to our green
hοuse gases. The uѕеd wateг іѕ rehеаtеd аnd working fluid іs κеpt seρагatelу.

Plumbing and Heating in South London's picture

It's really a nice and helpful piece of information.
I am happy that you simply shared this useful info with us.
Please keep us informed like this. Thank you for sharing.

Seo specialists's picture

I believe that is among the most significant info for me.
And i'm satisfied studying your article. But wanna commentary on few
general things, The website taste is great, the articles is truly great : D.
Excellent process, cheers

GTA 5 Cheats's picture

We're a group of volunteers and starting a new scheme in our community.
Your web site provided us with valuable info to work on.

You've done an impressive job and our entire neighborhood
will probably be grateful to you.

internet's picture

The Ferocious Panther Package with Ferocious Results.
Your Personal Message to 500,000 Fresh Contact Emails.
Each one collected by a double optin. Making sure they are interested in your service or
product. Most Customers find our Fresh Contact Emailings
Highly Responsive. Purchase Today For A Boost Of Fresh Contact Emails To 1,500,000.
Plus, Silver Submitter, Global Marketing and Classifieds.

sex stream's picture

Genuinely when someone doesn't understand after that its up to other viewers
that they will assist, so here it takes place.

watch Manny Pacquiao vs Brandon Rios's picture

The MMA forms of gloves are available in a variety of sizes -
8 oz. This is not going to be as much of an issue with
team sports that have a lot of standing room or limit their excess of speed to the running of the players.

He is known to have influenced other great minds of his generation including Thomas Edison for his patenting of the motion picture
camera.

teat maeonws's picture

He is known to have influenced other great minds of his generation including Thomas Edison for his patenting of the motion picture
camera.

Valentine&#039;s day 2014's picture

We're a group of volunteers and starting a new scheme in our community. Your web site provided us with valuable info to work on. You've done an impressive job and our entire neighborhood will probably be grateful to you.Thank you Siasat for OU Results

Post new comment