

Common JavaScript Gotchas - jblotus
http://www.jblotus.com/2013/01/13/common-javascript-gotchas/
PHP was my first programming language, and my initial exposure to JavaScript was through libraries like jQuery. There were things about JavaScript that always seemed to trip me up in the beginning due to how they worked differently than PHP. Heck there are still some things today that are confusing. I want to share some of the things that I struggled when I started working with JavaScript. I am going to cover the global namespace, this, knowing the difference between ECMAScript 3 and ECMAScript 5, asynchronous operations, prototypes, and simple JavaScript inheritance.
======
h2s
The most common gotcha I encounter in Javascript has to do with callbacks. I
see this problem all the time in my own code and that of my colleagues:
callbacks that have been registered either more or less times than the author
of the code expected. Usually more times.

This can manifest itself in many ways. Usually in the form of a UI element
being displayed more than once, but often more subtly such as a HTTP request
being sent more than once. Often the bugs only manifest themselves after a
certain sequence of actions, for example: click this UI element, check this
radio box, then hit submit and watch the net tab.

It's so often the root cause of Javascript bugs that if I or somebody else on
my team has a Javascript problem, I often start by asking myself if it looks
like it could be this. Lately I have begun to wonder if there isn't some
slight truth to that inflammatory "Callbacks are the new goto" story that was
on here a couple of months ago [1].

[1] <http://elm-lang.org/learn/Escape-from-Callback-Hell.elm>

~~~
damncabbage
_I see this problem all the time in my own code and that of my colleagues:
callbacks that have been registered either more or less times than the author
of the code expected. Usually more times._

I've yet to run into this problem before, and I'm an even split between JS /
Ruby these days. Are you building on top of any particular libraries or
frameworks? Could you give some examples of where you've encountered this?

~~~
FuzzyDunlop
I've encountered it once with a form, although it was a while ago and if I saw
the code again I might be able to identify what was wrong. In that case it was
probably a poor choice of element to attach to that caused the callback to be
fired independently multiple times on one click, and stopping the bubbling had
no effect.

The other time was in a Rails app, where a script was added to a partial for a
layout, and then added again later on (by a different developer) to the layout
itself. That caused a particularly nasty bug since it used 'toggle', and thus
the second callback negated the first.

------
fruchtose
I would also add that variables can be re-declared. Many beginners probably
think that writing this code would produce an error:

    
    
        var i = 0;
        var i = [];
    

No runtime error will be produced, and the script will continue normal
execution.

------
trip42
_a basic explanation is that by preceding a variable declaration with var
creates a property on the nearest containing function_

This is not true, the var hoist the variable and scopes it to the function,
but does not create it as a property of the function. A function is defined in
its outer function scope, an it's properties will persist across calls.

    
    
      function foo() {
        var bar = 1;
        foo.baz = 2;
      }
    
      foo();
    
      foo.bar; // is undefined
      foo.baz; // is 2
    

Adding properties to functions is useful for memoization, but is different
than what the var statement does.

Your summary of that section is a better explanation:

 _all variables are scoped to a function (which is itself an object), and
where you declare those variables with var determines the function they are
scoped to._

You might add, if you never declare the variable with var it is implicitly
declared global.

~~~
jblotus
thanks for the help

------
cmwelsh
One thing you didn't mention is strict mode. I think this rule is awesome for
preventing issues like in your "bonus gotcha".

~~~
tlarkworthy
yeah it should be your default JS environment

------
kylec
Using closures to encapsulate private variables is a good idea, but the way
this article recommends doing it doesn't demonstrate any of the benefit as it
doesn't really close over anything. I don't know if it's an example of good JS
code, but something like the basic closure definition of a counter might have
better demonstrated the ability to hide state:

    
    
        var counter = (function () {
            var i = 0;
    
            return function () {
                i += 1;
                return i;
            }
        }());
    

Where the internal variable, i, is inaccessible to anything but the counter
function itself.

~~~
jblotus
author here, it wasn't about hiding private variables. i was demonstrating
using closures to avoid global namespace collisions which i think is generally
a big problem for beginners.

~~~
catshirt
i believe you mean using functions, not closures. your post doesn't seem to
have the same misnomer, and simply explains lexical function scope. it doesn't
seem to touch on the closure, while your parent comment does.

~~~
jblotus
well, functions close over scope no matter what you call them.

~~~
catshirt
not exactly. closures close over scope. functions alone simply create a new
scope. these concepts are not synonymous.

if your function doesn't return another function, the references from that
function are deallocated once the function has executed.

when your function returns a function (a "closure"), the inner function closes
over the variables of the outer function, maintaining references to it's
context as long as you maintain a reference to the closure.

~~~
jblotus
ok i see your point. i conflated the terms function and closure in this case.

------
__herson__
That's why developers should always lint their code. www.jslint.com

~~~
damncabbage
Or <http://www.jshint.com/> if they feel jslint is too harsh or arbitrary
about some things.

~~~
niggler
jshint seems to be more actively developed, more receptive to changes, and
more flexible in terms of instructions (like ignoring certain patterns)

------
darrencauthon
If I only had a dime for the number of blog posts explaining what "this" means
in Javascript...

------
vojant
Great article, I will recommend it to every js beginner.

~~~
jblotus
thanks for reading

------
dleibovic
I thought php was also function scope, not block scope as the author
claims...?

~~~
jblotus
author here.

<?php $a = 1; /* global scope */

function test() { echo $a }

test();

in javascript, $a would be 1 but in PHP it is undefined and won't produce
output,

~~~
jblotus
after thinking about it for a while, I was misrepresenting what block scope
actually was and removed those references in the post.

------
camus
The article should be titled : fixing javascript flaws yourself.

