share
Stack OverflowCommon programming mistakes for JavaScript developers to avoid?
[+56] [54] Ahmed
[2009-07-27 14:37:35]
[ javascript ]
[ http://stackoverflow.com/questions/1188551/common-programming-mistakes-for-javascript-developers-to-avoid ] [DELETED]

In the spirit of

what are common mistakes we should avoid for JavaScript?

(11) I'm just impressed that this question has been up for 30 min and no one has yet answered with "The most common mistake for Javascript is 'using JavaScript'" - Brian Postow
(8) @Brian: :P Javascript, if used properly, is a decent scripting language. It's a widespread client-side browser language and it allows the use of first-class functions. It's not going to be as fast as C++ or Java, and it's weakly-typed, but I'd much rather see it than VB or any other scripting language. - Jason S
(7) @Brian: Javascript is actually a very good language. =/ - illvm
brian, do you mean using javascript at all or are u hinting for the capital S in JavaScript :) i really want the latter to be true because if javascript is a mistake, then it is unarguably the most popular and historically acclaimed mistake of all times :) - Ayyash
(1) I don't personally think that JavaScript is that bad of a language. (I have issues with the way it merges with HTML and PHP, but that may just be my office...) I just was surprised that no one ELSE had said it B-) - Brian Postow
Javascript is a very powerful language with a great flexibility. Thanks to its now you're using a so called Web 2.0...(Tell to the stackoverflow creators about JS... Brian, have you ever used JS seriously? I don't think! JS if used well is a great language! JS is like the C/C++ language: their liberty and their flexibility in how to make things make people to love or to hate them! - xdevel2000
The real problem people have with javascript is usually the DOM, or the difference in DOM between browsers, not javascript. - sgwill
@Brian, highly recommend watching Douglas Crawford's videos on JavaScript, especially the one on the "Good Parts of JavaScript". youtube.com/watch?v=hQVTIJBZook - AlexanderN
(10) The title of this post and the content of your post seem to be asking two different questions. - epascarello
(1) I kind of modified the title a bit to better match the question, but I think it still isn't perfect. - thomasrutter
Subjective? Should belong to community wiki, right? Or did the rules change? - Frunsi
lol, true. Funny that I gathered more points from my initial thoughts than a whole thread. :) - galambalazs
[+55] [2009-07-27 14:46:05] tyriker [ACCEPTED]

Testing in one browser and expecting it to work in another.


(3) thats a DOM mistake, not a javascript, right? - Ayyash
No, it applies to both. I've seen pure JS that works in FireFox, Chrome and Opera that fails in IE. - staticsan
staticsan, I would love to see an example of pure JS which works in one browser and doesn't work in other. - SolutionYogi
@SolutionYogi: How about Array.forEach() ?? - jason
@jason, as far I know forEach is not part of the ECMA-262, edition 3, means that this could not be implemented in IE - Mike Chaliy
Mike Chaliy, it's still Javascript (note that Javascript isn't exactly ECMA-262, it's the Netscape/Mozilla scripting language based on ECMA-262) that works in some but not all browsers. Other examples would be various implementations of getters/setters, or XML literals. - eyelidlessness
1
[+42] [2009-07-27 15:20:02] SolutionYogi

1. JavaScript has only function scope unlike other C like languages which have block scope as well as function scope.

function test()
{
    var age = 10;

    var name = 'yogi';

    if(name === 'yogi')
    {
        var age = 20;
        alert(age); //alerts 20.
    }

    alert(age); // woohoo. alerts 20.
}

2. Be careful with your semi colons and commas in JavaScript.

function test()
{
    return //JavaScript will insert an automatic semi colon here.
    {
        output : true
    }    
} 

alert(test()); //alerts undefined.

3. Suggesting that you won't use a JavaScript library because the project is too small.

4. Trying to change JS so that it fits your existing knowledge. I am looking at you Objective-J [1].

5. Not understanding how 'this' works in JavaScript [2].

6. To believe that in JavaScript, everything is an object. There are primitive types in JavaScript.

function test()
{
    var person = "yogi";
    person.age = 100;
    alert(person.age); //alerts undefined.
}

That's all I can think of right now, will add more as I think about it some more.

[1] http://objective-j.org/
[2] http://stackoverflow.com/questions/1007340/javascript-function-aliasing-doesnt-seem-to-work/1162192#1162192

(2) The brace-style you're using can exarcerbate semi-colon problems. This is the first time I've realized this is possible. - staticsan
(1) Yes, the brace style makes this problem serious. I believe that this brace style is common enough that you may face this problem and waste hours to debug the issue. - SolutionYogi
I'm not sure that Objective-J is trying to "change" JavaScript—Cappuccino/Objective-J is just a web framework that allows you to write web apps in a Cocoa-style environment. - Steve Harrison
2
[+29] [2009-07-27 14:42:12] Mike Chaliy

Missing var, and because of this magic error, when i is changed out of the expected scope:

for(i = 0; i < 10; i++){
}

should be:

for(var i = 0; i < 10; i++){
}

To clarify:

var i = 10;

function ii() {

   for (i = 0; i < 10; i++) {
      test();
      alert(i);
   }

}

function test() {
   i++;
}

ii();

Output:

1, 3, 5...

With

for (var i = 0; i < 10; i++)

Output:

1, 2, 3

(37) I think I'd advise against using the same variable name while nesting for loops. That's not a common JS mistake, that's simply bad programming. - doomspork
Can you further explain the code above? How does this not cause the outloop to terminate after one iteration? In most programming languages, what you do is explicitly denied as it causes compile errors because you are re-declaring a variable of the same name. What is happening here? - Matt
(4) @Doomspork this is just illustration of scopes. I can modify example to show this error without innerloop with the same name. For example there possibility to change i in closures. - Mike Chaliy
(2) @Matt: you can write var i=10 a thousand times in a row and it will still work. JS is basically a giant map. Using var only places the variable in the current scope. While not using it places it globally. - geowa4
(4) for does not create scope in JavaScript. Both loops won't work right in the exact same way (inner terminates outer). The only difference is that the second one doesn't create a global variable if run within a function. - Borgar
(1) This is a bad example. Depending on the Javascript implementation, you will either have a single variable shared between both loops or you'll get a runtime error for declaring "var i" twice in the same scope. - 17 of 26
(1) @Borgar is right. JavaScript doesn't have block scoping. That's why I never do the var declaration in the for--it misleads people. - Nosredna
@17 of 26, You can use second example. It does not depened on implementation. Example with for IMHO simplier to understand. - Mike Chaliy
Your second example is incorrect - variables are scoped to functions, not blocks, so the inner loops use of "i" as an identifier will refer to the same variable as the "i" in the outer loop. See ECMAScript 262, sections 10.1.3 and particularly 12.2: "...variables are defined with function-local scope... A Block does not define a new execution scope. Only Program and FunctionDeclaration produce a new scope." - NickFitz
@NickFitz, sure it incorrect, this is something that I wanted to show. This is example of programming error, I have hade in past in inherited code. - Mike Chaliy
3
[+26] [2009-07-27 14:58:32] Joel Coehoorn
var x = "0100";
var y = parseInt(x); // result _could_ be 4, 64, or 256 -- no radix specified

Do this instead:

var x = "0100";
var y = parseInt(x, 10); // result WILL be 100

(6) I thought that parseInt used base 10 by default. Is there a situation where parseInt(x) would return 4? - DisgruntledGoat
(9) It doesn't have to. For example, try giving it a leading zero with no radix. "010" returns 8 on my system (XP/FF3.5). That's why it's a common mistake. - Joel Coehoorn
(4) The result could also be an error. I see this most often when parsing dates, where "09" is quite common, but an invalid octal value. - Bill the Lizard
the most common place this happens is with parseInt(09); - voyager
The original phrasing is misleading: parseInt("100") WILL be 100, always, but when the string is not constant, it may be interpreted differently than what the user expects. - Marius Gedminas
Yeah, the result will be 100 on any browser. The danger is that the programmer changes the constant to something like "099" to preserve visual spacing. - Nosredna
4
[+25] [2009-07-27 14:49:34] chaos

Putting a comma after the final element of an array/object literal, like any sane language allows you to, and in fact JavaScript does on any browser that doesn't suck.

Yes, IE's fascist comma syntax irritates me a little tiny bit.

Example:

var newObj = {
   foo: 1,
   bar: 2,
   baz: 3,    // works on any browser that doesn't suck
};

var newObj = {
   foo: 1,
   bar: 2,
   baz: 3     // works on IE
};

Code example? I don't know what you mean. I've never seen commas after the last element of an array. - DisgruntledGoat
(2) perl and php allow commas after the last element of an array. This lets you write the last element as any other element, and lets you add/delete elements anywhere in the array without having to care about the position. - Alsciende
Exactly. I can't remember whether this is part of the ECMAscript standard, or not, but in any case you can do it in Firefox but not IE. - Jason S
It is part of the standard. IE properly claims that it's invalid Javascript, and Firefox stupidly doesn't care. - seanmonstar
(4) @seanmonstar: Actually the standards says that you can have the last remaining comma, IE is the one that doesn't got it right... - Pablo Cabrera
(7) the trailing comma is ugly and confusing to me. It leaves me thinking there's another element in the array that's got a ton of whitespace before it, so it's off the screen or on the next line or something else. I waste a lot of time hunting for it. Unless you're generating the code by machine (don't do that...), there's no reason for the last comma. - rmeador
(10) Except, y'know, we've already discussed the important reasons for the trailing comma -- that it lets you write elements identically and rearrange them at will. Have you seen the horrible things people do to cope with not being allowed a trailing comma -- the leading commas on lines, for the love of God? - chaos
Wow, never knew you could do that. I'm sure PHP has spit its dummy if I've accidentally done that before. Thanks for the tip. - DisgruntledGoat
5
[+20] [2009-07-27 14:41:55] Brian Ramsay

Don't use document.write().

Declare variables with var (keeping them from being globals).

Read Javascript: The Good Parts [1] - an amazing (and concise) book by a Javascript pioneer that will answer this question perfectly.

[1] http://oreilly.com/catalog/9780596517748/

(4) What do you use in place of document.write()? - Gary Willoughby
(3) I use DOM manipulation, e.g. document.getElementById('someEmptyDiv').innerHTML = 'some dynamic content'. - Marius Gedminas
6
[+17] [2009-07-27 14:40:31] chaos

Rookie mistake #1: Building difficult, browser-compatibility-sensitive operations by hand instead of using jQuery.


(7) Or any of the other libraries. - jason
This has hardly anything to do with being a rookie, but maybe a programmers "heritage". What do you think people did 10 years ago, when no JS Frameworks existed, and there were 100 different browsers and versions that handled HTML all differently? It takes time to learn new stuff. - TFM
I have that exact same heritage -- I installed the first httpd at my college in 1992 -- and I picked up jQuery in about 5 minutes when I got over my "eww libraries" problem. There is no excuse. - chaos
(14) Rookie mistake #2: Thinking there's nothing outside jQuery, when in fact there's plenty of other good libraries -- and sometimes no library is the best choice. - Alsciende
(44) Rookie mistake #3: Using jQuery without understanding Javascript well enough to use it. - Jason S
actually, no rookie should be allowed to use a library, because as rookie mistake #3 suggests, its a mistake :) - Ayyash
I started with jQuery, then Dojo, then YUI. I found YUI to be easier to use, but it's slow as a dog (maybe it's just me). Lol. - Chris Kaminski
I disagree, you can use jQuery even if you dont know Javascript, my co-workers for example are using my validators and by id selectors. if they had to use JS than they would not use it. - IAdapter
Yes you can use jQuery without JavaScript knowledge, but... you shouldn't - 999
Regarding #1, I think it's important to recognize that while that may be a rookie mistake, a rookie shouldn't really be tasked with building anything of that nature that's mission-critical, and a veteran choosing to not use jQuery (or any library) needn't be a mistake. - eyelidlessness
7
[+12] [2009-07-27 14:42:57] chaos

Using any of escape(), encodeURI(), and encodeURIComponent() when you need one of the other ones. This is really good at introducing incredibly subtle, hard-to-debug errors into Ajax interactions. See this lovely comparison of the three [1].

[1] http://xkr.us/articles/javascript/encode-compare/

8
[+12] [2009-07-27 18:46:59] Shog9

Using eval() to access properties by name...

function naiveGetProp(obj, name)
{
   var fullname = "myProp" + name;
   return eval("obj."+fullname); // should just return obj[fullname]
}

Not sure why variations on this show up so often, but it makes me cringe whenever i see it - i try not to demonize eval(), but this is just plain silly.


+1. "eval()" is certainly a useful tool (for example, it's great for decoding JSON), but it is really annoying when people use it unnecessarily. - Steve Harrison
(1) @Steve: !?!?!?!? JSON is <s>a terrible</s> the worst possible tool for decoding JSON. JSON.parse() - Hello71
9
[+12] [2010-07-01 00:00:58] galambalazs

Gotchas

  • using for.. in for arrays (use simple loop, because Array properties can interfere)
  • relying on global undefined, which can be modified (define your own)
  • not using var for local variables
  • using more than one var for the same variable (can be confusing, error prone)
  • checking "if (somevar)" to see if it's defined, when somevar can be 0, false, or "" (empty string)
  • polluting global scope (possible collisions)
  • misusing closures and causing memory leaks (release event listeners!)
  • using browser sniffing (use feature detection instead)
  • augmenting host objects (don't do that, they cannot be trusted)
  • augmenting native objects too much (anyone can overwrite your functions)
  • not using built-in functions (learn the language!)
  • forgetting to use new for constuctor functions (convention: capitalize first letter)
  • typing/see new, and think: I know this stuff from somewhere (it's not Java)
  • unconsciously initializing variables to null (it's not C/C++ either)
  • not realizing that functions are objects (yes they can have properties)
  • relying too much on floating point arithmetic (check: 0.1 + 0.2 == 0.3)
  • not realizing the difference between == and === ( the last one is safe, use == if you know it well)
  • not realizing that arguments are passed by reference (except primitive types)
  • changing the arguments array
  • relying on semicolon insertion

Learn the language. Always do things for a reason. If you're not sure about something, go and see the specification.

A related thread: How to write high quality Javascript [1]

[1] http://stackoverflow.com/questions/3142250/how-to-write-high-quality-javascript/3142451#3142451

-1 for the first point, a for..in.. may not result in optimal performance, but its neither a gotcha, nor a mis-use, nor an error! - Frunsi
(4) @frunsi: Using for..in without testing for hasOwnProperty has caused more than a few unexpected errors. - Dave Ward
(1) @frunsi: until someone thinks it's a fun thing to extend the Array object. See: jsbin.com/abiwe3/3/edit, also yuiblog.com/blog/2006/09/26/for-in-intrigue - galambalazs
@dave: okay, right (gave you +1 now). But in the end, it all is, because of false assumptions (well yes, gotchas are there because we have false assumptions) - Frunsi
@galambalazs: I didn't miss that sentence, IMHO it should be the only answer ;-) - Frunsi
@galambalazs: No, will not remove it. In most cases, a for..in.. loop is still ok. - Frunsi
@frunsi would make SO such a great place. full of lmgtfy... - galambalazs
@frunsi than you are exactly the guy whom Talvi Watia should fear... It's web programming. It's widgets. It's libraries. You can't trust what you don't own. Laziness doesn't help. - galambalazs
@galambalazs: what's the problem? what does "lmgtfy" mean? help me? - Frunsi
(3) @frunsi now it's kind of a recursion btw... bit.ly/cCNCVM :) - galambalazs
@galambalazs: come on, I gave you +1, your list is fine, you don't suck, JS sucks :D no really, JS has some strange rules, but if you know how it was meant (YOU know), if one knows JS rules, then they make sense. Plz don't lets start a flamewar - Frunsi
@frunsi you may be flaming I'm just defending quality over misconceptions, laziness, stubbornness. I don't care childish points and such.. - galambalazs
@galambalazs: I'm german, so please speak slowly :D hell, yeah, lmgtfy or "lmdfdg" in german. - Frunsi
@galambalazs: well... I've written my points. It makes no sense, all I can do, is "take away" that +1 and go to bed now. GN8 (and if you feel so, then you're free to start a flame-war now.. its in vain anyway). Thought, your list was ok, it was not bad :D I don't care - Frunsi
no hard feelings, but all comments should be removed because they are unrelated to the question except no 2,3 - galambalazs
(1) @galambalazs - Weren't you feeling lucky when you posted that link? There, I fixed it - bit.ly/RnQXS - Anurag
@Anurag Definitely. I forgot that feature... :) - galambalazs
@galambazs must be a guru!!! he defends quality over misconceptions, laziness, stubbornness. He doesn't care childish points and such.. and he feels, that pts 2 and 3 should become history, while anything else should be removed. harhar - Frunsi
@galambazs: for the history, you wrote: "@frunsi would make SO such a great place. full of lmgtfy... – galambalazs 1 hour ago" - Frunsi
@galambazs: and for the history your next comment was: "@frunsi than you are exactly the guy whom Talvi Watia should fear... It's web programming. It's widgets. It's libraries. You can't trust what you don't own. Laziness doesn't help. – galambalazs 1 hour ago" - Frunsi
@galambazs would make SO such a great place. full of people disrupting any professional conversation. - Frunsi
10
[+11] [2009-07-27 14:42:30] Colonel Sponsz

Failing silently when JavaScript is disabled on the client.

Ideally we should all be using progressive enhancement [1] so there is no loss of core functionality when JS isn't available.

  • Edit: Sometimes some people have to use JavaScript for a task. If you do then put in a suitable <noscript> trap - even at page level. Don't just leave items that do nothing at all when you try to interact with them without JS.
[1] http://en.wikipedia.org/wiki/Progressive%5Fenhancement

(9) this is a point of some contention though. there aren't many people with js disabled. and if you are building an ARIA, you often need to use javascript for some tasks. - geowa4
(2) More people have javascript issues than you think: reportedly 1 visitor in 20, and that's not counting Google, some smart phone users with poor javascript support, and NoScript users. And if you work for the US Govt you are required to support screen readers, and that typically means working with javascript turned off. - Joel Coehoorn
(1) @George IV - Hence my italics round /core/. It might be a poor user experience with JS disabled but you should at least be able to perform the important operations without it. And if you can't it should tell you rather than just leaving mouse clicks that do nothing. - Colonel Sponsz
-1 You do know that not everybody knows english, so why you did not provide version in every language? i think more people dont know english that have JS turned off. - IAdapter
11
[+10] [2009-07-27 14:42:24] Lloyd

Declaring local variables without var keyword.


(1) Right, otherwise they become global. Using the var keyword in global scope still makes it global. But I had problems with some browsers when i omitted this keyword. So I suggest you to try to always use it, even if it's in global scope. - jamolkhon
12
[+10] [2009-07-27 15:12:32] Dan Diplo

Forgetting that in JavaScript data constructors that the numbers for the months January to December range from 0 to 11 (so that month 1 is February, not January).


13
[+8] [2009-07-27 14:50:47] Mehmet Aras

Some resources to check out:

[1] http://www.jslint.com/
[2] http://net.tutsplus.com/tutorials/javascript-ajax/24-javascript-best-practices-for-beginners/
[3] http://www.crockford.com/
[4] http://rads.stackoverflow.com/amzn/click/0596517742

Here's his Google techtalk too: youtube.com/watch?v=hQVTIJBZook - Anon
It's definitely well worth the time. This is the first time I came to know of JavaScript's automatic semicolor insertion and I was shocked by how one's coding style (i.e. putting curly braces in the next line) can result in serious bugs due to how the code is interpreted. It was very educative and at the same time it goes to show that you really need to get familiar with the tools and languages you're using in order to avoid learning things the hard way. - Mehmet Aras
+1 for JSLint and The Good Parts. - ojrac
Just don't hold up Mr Crockford as a god, because he's not. - staticsan
14
[+8] [2009-07-27 15:16:53] Frew

The fact that javascript "doesn't require" semicolons at the end of lines can lead to bizarre bugs. Here's an example:

return
    { 
       foo: 1 
    };

This won't actually return the object because it will parse if the parser adds a semicolon after the return. You really need to use 1TBS [1] in situations like this.

As asked for, this should be

return {
   foo : 1
};
[1] http://en.wikipedia.org/wiki/1TBS#Variant:_1TBS

Can you clarify what the code should be. What is a TBS? - user53791
15
[+7] [2009-07-27 14:40:57] Josh E

accidentally comparing anything (like an int, boolean, etc) to a string without type checking (i.e. the === operator)


16
[+5] [2009-07-27 14:59:50] Clay

Not being careful with the use of "this"...


(9) I like your answer, but you should elaborate, because this isn't really helpful. - Alsciende
See the link for #5 in SolutionYogi's answer for more info. - Joel Coehoorn
(5) "...because this isn't really helpful..." har har har. - Zack The Human
17
[+5] [2009-07-27 15:07:31] AcousticBoom

Simple thing but all too often, whether out of laziness or whatever, many JS coders tend to leave out the semi-colon at the end of a line.


18
[+5] [2009-07-27 18:04:16] Carl Manaster

Failing to understand closures. [1]

[1] http://stackoverflow.com/questions/1039680/why-cant-i-roll-a-loop-in-javascript

19
[+5] [2009-07-29 05:08:03] Imagist

Using client-side JavaScript to do things that should be done server-side.


(2) Presumably you mean using client-side Javascript; the language can also be run server-side. - eyelidlessness
Indeed. Such as relying on Javascript to do validation without server-side validation to back it up. - mmacaulay
@eyelidlessness I was aware that this was possible, but I am not yet aware of anyone actually doing it. - Imagist
20
[+4] [2009-07-27 14:43:15] geowa4
  • Using !=/== instead of !==/=== to check type as well as equality. "1"==1 is true; "1"===1 is false
  • Not understanding scope. var keeps it in the local lexical scope. Not putting it there puts in globally.
  • All browsers are different [1]. Make sure your code works in the ones you care to support.
  • do not use for(var item in myArray)*

*: It just happens to work because the functions, like join are marked as non-iterable. If you extend the array (as many libraries do, your code will break). That construct is meant for iterating over object members. For example:

var obj = {variable1: "hello", variable2: "world", 
           function1: function() { 
               alert("func"); 
           }
          };
for(var p in obj)
    alert(p + ": " +obj[p]);
//p will equal "variable1", "variable2", "function1"

var arr = ["a", "b", "c"];
//using the same construct as above still works, but just wait.
arr.myFunc = function() { alert("uh oh"); }
//now looping in that same way will cause p to be "myFunc" in an iteration
//which you may not have intended
[1] http://www.quirksmode.org/dom/w3c%5Fcore.html

(1) Could you add an explanation? - Sarah Vessels
to each point? or one in particular? - geowa4
(1) Would you expand on that last point please? - Sukotto
(3) I would phrase your third point as "Don't use libraries that make the mistake of adding properties to the core objects" - if the creators of the library made that mistake, who knows what else they'll have got wrong ;-) - NickFitz
So you're saying don't use Rails. The included Prototype library does that. And that's my fourth point, but I'll let that slide - geowa4
Come on, there is nothing wrong with prototyping when done sensibly, the 'core' javascript is meant to be extended... this is what makes it so powerful. - Dimitar Christoff
don't get me wrong, there is nothing wrong with it at all. just one mistake that i see all the time is the for..in construct, which has unintended side effects when the object has been extended. if your intent is to loop through the properties of the array, go for it. but if you want to loop through the elements, use a counter. - geowa4
@Dimitar, he said adding properties not prototyping. - jason
21
[+4] [2009-07-27 14:46:57] Jason S

Using eval() for almost any purpose.


I'd say using eval for any purpose at all! - Pablo Cabrera
@Pablo: by the user: I agree. In general: JSON parsing, if not built in to the browser, requires eval for efficiency (technique = validate then evaluate). - Jason S
As the saying goes evil is eval. - Ethan Heilman
(2) The problem with sayings is the folks who forget why they're said but keep "saying" them anyway... - Shog9
22
[+3] [2009-07-27 14:39:37] chaos

Trying to use objects as property names / associative array keys. For several purposes it will look as if it worked, but it didn't; the object was coerced to a string representation.


(1) I fail to see how this is a programming mistake. As long as you know that Object.prototype is not extended, there's nothing to be afraid of. An object is really an associative array. - Alsciende
(5) That's not chaos's point -- the point is you can't use objects as a key in an associative array. - Jason S
23
[+3] [2009-07-27 14:42:42] Daff

One mistake I experienced was that programmers are trying to apply e.g. common Java or C++ design patterns to JavaScript that didn't make any sense in that language and therefore overcomplicating JavaScript development.

jQuery or many other libraries/frameworks may have at the beginning a quite uncommon approach (for old school OO typed language developers) to solve problems but it is usually way more effective once you got into it.

An of course not using one of the great libraries is a huge mistake, too.


Not using a library may be a mistake, it isn't necessarily. It depends entirely on what you're trying to accomplish, your familiarity with the relevant problem area(s) covered by the library, and a whole lot of other factors. - eyelidlessness
Most libraries/frameworks are built to tackle recurring tasks in developing web pages and I think there are only very few use cases where no library can/should be used at all. - Daff
24
[+3] [2009-07-27 14:49:36] Bill the Lizard

Trying to add the value of two numeric string objects, usually from text input, which results in a concatenation of the strings. You have to parse the numeric value of the strings with parseInt() [1] or parseFloat() [2] first.

[1] http://www.w3schools.com/jsref/jsref%5FparseInt.asp
[2] http://www.w3schools.com/jsref/jsref%5FparseFloat.asp

25
[+2] [2009-08-11 19:46:37] Joshua

Instead of listing common mistakes, as there are way too many, I've focused on a few simple points that if covered avoid many of the mistakes.

  1. Understand scope in javascript. Using variables appropriately and knowing where the variable you've assigned will be accessible leads to much tighter scripting.

    See this article [1].

  2. Understand how to declare variables as private, public or privileged. Not everything has to be on the global namespace. Working inside a box and knowing that you're not going to "knock" anything else over leads to greater certainty of stable code.

    See this article [2].

  3. Declare arrays like:

    var a = [];

    instead of

    var a = new Array();

    Declare objects like:

    var b = {};

    instead of

    var b = new Object();

  4. Understand how JSON is formed and use it appropriately. Not only is it a lightweight data-interchange format that can be used instead of XML, it also serves a very useful role in structuring series of public properties within an object.

    See http://json.org/.

  5. Format your JavaScript correctly. It should be:

    var fn = function(){
        var myVariable = 213;
        var myPrivateFunction = function{
            // do something
        };
    };
    

    and not:

    var fn = function()
    { // <-- notice the bracket here..
        var myVariable = 213;
        var myPrivateFunction = function
        { // <-- notice the bracket here..
            // do something
        };
    };
    
  6. Use FireBug or a similar debugging utility to step through scripts, create scripts in real time, examine the DOM, and so on.

  7. Compress JavaScript files, ideally to a single file in release (putting them at the end of the body tag allows the rest of the page to load before the scripts are processed).

There are several others that I would suggest if they had not already been listed such as "use JSlist", "read Douglas Crockford's (the Good Parts) book" and so on. Keep learning.

[1] http://www.smashingmagazine.com/2009/08/01/what-you-need-to-know-about-javascript-scope/
[2] http://www.crockford.com/javascript/private.html

26
[+2] [2010-07-01 00:41:14] CrazyJugglerDrummer

Mistake: using == instead of ===. Solution: use ===

JavaScript truth table:

''        ==   '0'           //false
0         ==   ''            //true
0         ==   '0'           //true
false     ==   'false'       //false
false     ==   '0'           //true
false     ==   undefined     //false
false     ==   null          //false
null      ==   undefined     //true
" \t\r\n" ==   0             //true

Source: Doug Crockford

(=== returns false for all of these)

Mistake: using eval. Solution: don't. (you can use o[foo] instead of eval("o."+foo)


(1) Should read: "Mistake: using eval. Solution: don't. (you can use o[foo] instead of eval("o."+foo) - Frunsi
27
[+1] [2009-07-27 14:46:53] idrumgood

From a non-technical standpoint, one of my own personal biggest mistakes was diving right in and trying to write all my own code to solve my problems.

Turns out, it's next to impossible to encounter a problem that no one else has already solved, so do yourself a favor and spend 5 minutes searching 'snippet' websites to see if there is already a solution.

As far as technical mistakes, since javascript is loosely typed, it's easy to accidentally compare two values like an int to a string or something.


28
[+1] [2009-07-27 17:52:52] Shog9

Running a RegExp object created with the g flag multiple times without taking into account the state of the lastIndex property [1]...

[1] http://stackoverflow.com/questions/894696/why-is-the-javascript-regexp-test-method-behaving-as-a-toggle

29
[+1] [2009-07-27 17:59:43] Shog9

Trying to add properties to an object by modifying a property named "prototype", rather than modifying the prototype property of that object's constructor function...

var obj = { ... };
obj.prototype.blah = function() { ... }; // does not do anything useful

Sure it does something useful. It throws a TypeError. - eyelidlessness
Heh... ;-) - Shog9
30
[+1] [2009-07-27 18:15:02] ojrac

Using global variables.

This is mostly a problem on large projects, when you use someone else's variable names. The solution is to hide all of your code in namespaces or closures. For example:

Running code without overwriting other variables:

(function() {
    var a = 2;
    var b = 2;

    var sum = a + b;
    alert("By the way, " + a + " plus " + b + " is still " + sum);
})(); // this creates and then calls the anonymous function

Putting code in a namespace: Basically, just use a lot of dictionaries.

<script type="text/javascript">
if (!window.myprogram) { // make sure the namespace is "declared"
    window.myprogram = {};
}

myprogram.myapp = {
    variable1: 2, // vars and functions are declared the same way
    function1: function(a, b) {
        return a / b; // whatever
    }
};
</script>

31
[+1] [2009-07-27 18:19:51] Demián

Using arrays as associative arrays...

var a = new Array(); // ugly syntax...

a['key'] = 1;

should be rewritten as

var a = {}; a.key = 1;


(3) Or just var a = {key: 1}; ... - Shog9
32
[+1] [2009-07-27 19:22:18] Chetan Sastry

Not realizing javascript always uses floating point arithmetic leading to nasty surprises.

  • When dealing with calculations involving money.
  • Dividing by 0 yields Infinity, not an error/exception. Careful when looping through an expression resulting from a division.
  • NaN is poisonous (anything you do with it results in NaN) as in, Welcome back undefined, there are NaN items in your shopping cart.

33
[+1] [2009-07-27 22:41:40] Ayyash

Re-usability

my ever lasting mistake with javascript is that ridiculous notion that crosses my mind every time i create a new function: "im not gonna use that again, so no need for it to be reusable"! I usually come back to it in less than two days to reuse! lesson of the day: always think ahead when it comes to Javascript, its pretty expensive

the # pain

inspired by an answer above, using the # as a value for an href attribute just because you are relying on the onclick is a BIG BIG MISTAKE, # is a link to a named anchor, use a valid url and return false onclick

<a href="#" onclick="function(){...}">link</a> // mistake

<a href="http://myalturl-incase-js-is-off.htm" onclick="function(){return false}">link</a> // correct

or, same as above and on load, call a function to remove the href attribute

$("a.myanchor").attr("href","javascript://");

34
[+1] [2009-07-29 13:04:05] vvo

trying to use setTimeout this way :

setTimeout("myFunction('test', 8)", 500);

!


I'm not sure how that's a mistake. It works. It's just ugly. - eyelidlessness
yes but you'll never learn javascript if you use this syntax ... - vvo
35
[+1] [2009-07-31 03:49:13] BenRady

Not using JSLint [1]

[1] http://www.jslint.com/

36
[+1] [2010-07-01 00:11:25] Ondra Žižka

JavaScript stops running because an exception is thrown and not caught. They are actually caught in the browser's code (mostly the event processing loops).

To avoid these unintended halts, use:

try {
   alert( undefined.thisThrowsUndefinedException );
}
catch( ex ) {
   alert( ex );
}

Most common mis-uses of javascript is imho coding for just one browser and not testing for the others.

And how to fix them -

  • Use libs like jQuery, dojo, prototype,
  • or use frameworks which are well tested like JSF & RichFaces
  • Test with MSIE & FF. The others will be usually covered by FF testing.

(1) come on.. exceptions are one thing, but not the most common! - Frunsi
frunsi, the original title of the question was "Why javascript stops executing on error" or such. The most common reason (if not the only one) is an uncaught exception. - Ondra Žižka
37
[0] [2009-07-27 14:49:28] Sukotto

Always taint-check strings before adding them to the DOM, calling eval(), or doing anything that might expose the string.


38
[0] [2009-07-27 17:42:04] Matias

HardCoding clientIds to manage the DOM if wou're working under asp.net


I dont know asp.net, but why thats bad? for example in java in some frameworks ids are auto-gen and look like j13:j14:j83 .. its better to hardcore id. - IAdapter
We converted our asp.net project to use master pages, which ended up changing all the client ids. It was a nightmare searching through years of javascript trying to find all the failing elements that had been hardcoded. - tessa
39
[0] [2009-07-27 18:49:10] Tom

Javascript in HTML.

Enough said.


Not really. - Shog9
(1) Why is this downvoted so much? I agree with the answer. Javascript inside the HTML pages is akin to ASP/PHP spaghetti code with logic inside the html files. Ideally, JS should all happen unobtrusively in separate JS files - infinity
40
[0] [2009-07-28 00:47:43] CMS
  • Think in portability and distribution, don't pollute the global scope.

  • When comparing variables, use the strict equality operators (=== and !==) to add type cohesion:

    1 == true  // true
    1 === true // false
    0 == ''    // true
    0 === ''   // false
    
  • Be careful with the falsy values: 0, NaN, '', null and undefined are all false in boolean expressions.

  • Don't use eval to parse JSON... use a JSON Parser...


41
[0] [2009-07-29 13:10:27] mwilcox

Using reserved words. Especially if you are coding to Firefox which is (mistakenly) very permissive about them. Some of the ones that have gotten me (sometimes more than once):

var int;
var export;
var import;
var float;
var abstract;
var public;
var class; // this one seems obvious but it happens often
var const;

A quick search for JavaScript reserved words will get you the whole list.


42
[0] [2009-07-31 19:13:51] Martin

Don't use Javascript to replace CSS. That is my only golden rule when it comes to Javascript.


43
[0] [2009-08-02 01:57:42] Mehmet Duran

Suppose you've got some buttons in your HTML page. And you want to operate on them. Here's a small script block, that alerts the index number of the button relative to the DOM.

var btns = document.getElementsByTagName("button");
for( var i = 0; i < btns.length; i++ ){
    // I know, I know, IE won't be running this bit. More on that later.
    btns[i].addEventListener( "click", function (){
        alert( "Hi, I'm button #" + i );
    }, false );
}

Lovely. Let's say we've got 8 buttons. Click on the first one and it should say "Hi, I'm button #0" right? Hey, wait a second, it says #8? What? All the buttons say #8? What's going on?

What's going on is, that little i variable at the end is still in the scope you've set the event listener. And it's 8. Because you've been telling it to increment itself while you were busy setting events in a for loop and you told the for loop to quit if i was bigger than 7. So i sits there waiting for you to call it's scope, holding onto the last value it was assigned.

So what do we do? Closures! We create a small closure inside the for loop to capture the value of i and use it in our event.

var btns = document.getElementsByTagName("button");
for( var i = 0; i < btns.length; i++ ){
    (function (index){
        btns[index].addEventListener( "click", function (){
            alert( "Hi, I'm button #" + index );
        }, false );
    })(i);
}

Instead of 1, now we've got 8 closures. And IE is leaking precious memory but, what the hey, we've got what we asked for, right?


44
[0] [2009-08-11 19:57:15] Joshua

Don't add unnecessary members to the Object prototype. This can S.E.R.I.O.U.S.L.Y slow down your application because everything inherits from object.

for example:

object.prototype.contains = function(membername, membervalue){
   // some processing
}

could be better written like this:

objectContainsMember = function(object, membername, membervalue){
   // some processing
}

45
[0] [2009-09-29 20:02:56] infinity

Common mistake: Using Javascript arrays like hash tables or PHP-style of arrays.

var currentUploadsArray = [];  

function hypotheticalUploadFunction()
{
    currentUploadsArray.push('a');
    currentUploadsArray.push('b');
    currentUploadsArray.push('c');
    //currentUploadsArray holds: ["a", "b", "c"]

    // .... do stuff ...

    delete currentUploadsArray['b']; 
    // returns true, but doesn't do anything.
    // currentUploadsArray now still holds: ["a", "b", "c"]
    // Why? because JS arrays are supposed to be numeric indexed only.

    // Let's try to delete by index.
    delete currentUploadsArray[1];
    // Another gotcha:
    // returns true, but doesn't remove the item from the array, it sets it to undefined:
    // currentUploadsArray now holds: ["a", undefined, "c"]

    // So now if you check for the length, it still says 3:
    currentUploadsArray.length; // 3

    delete currentUploadsArray[0];
    delete currentUploadsArray[2];
    currentUploadsArray.length; // Yep, still 3.

    // This sucks because there's no easy way to see if the array is empty, 
    // thus making it useless for a lot of common things, like a queue.
}

46
[0] [2010-07-01 00:33:30] Frunsi

IMHO there are no most common mis-uses of javascript, but there is a large list of re-occuring syntax, syntactic and other errors (probably leading to exceptions). But its hard to priotirize those. Point.

If you really want an answer, then either do a survey (e.g. community wiki on SO), or write a software, which finds and analyses those errors on a list of websites.

But, the list of mis-uses that finally lead to errors is really, really long.

If there'd be a list of common errors, then those would be fixed meanwhile on most sites.


now i see why you are downvoting... "write a software, which finds and analyses those errors on a list of websites". If that would be that easy... "If there'd be a list of common errors, then those would be fixed meanwhile on most sites." so let's not bother gathering them, because those sites would actually work. We cannot let that happen, right? :) - galambalazs
oh, and you forgot the "everything is relative" part. very constructive points btw. :) helped me a lot. - galambalazs
I miss your point, maybe I am just stupid. My words may be stupid, very stupid, I should start down-voting all of my posts, should I? Come on... what is the problem? What have I done, that you so very much like to stalk me? - Frunsi
you: 1.) confuse others 2.) are not open to any critique 3.) downvoting, spamming just for revenge 4.) still not sleeping - galambalazs
you 1.) like to defame me! jsbin.com/abiwe3/3/edit: "guy1: (let's say frunsi)" - that example is totally out of context. I have written my points, I DID NOT START TO GET PERSONAL. And, I even gave you an upvote after you have have convinced me! So... WTF? Also, my statements about this very single question are still my opinion, you may accept it or not. No problem, I can live with it. And yes, I down-voted three of your other, unrelated answers.. but I read them and searched for real errors. Maybe this helps you to just stop stalking :D Somehow it feels, like it could be funny :D - Frunsi
"I even gave you an upvote." Oh, I missed that. Maybe I should've praised you for that. I'm always criticizing what someone says not who says it. You're admittedly doing the other way. But you didnt get personal. No... You helped the community so much. Sleep well. - galambalazs
Oh no, I just gave you just two down-votes (should it have been more? no, would be unfair..), and just one up-vote for your on-topic answer. Well.. I still don't understand your problem. What have I done?? Give me a reason.. you can read any single line in all my answers and comments of this question. And to repeat it one more time in compact an INCOMPLETE FORM: (don't feel offended) RTFM! JS is different that what most people expect. And the question should belong to community wiki. Good night, and calm down (and before you spit again, READ IT). I've repeated it more often than I'd like to.. - Frunsi
Just one more time: READ what I've written, think about it (and while doing it, try to ignore any personal indisposition for some seconds). I did the same on your stuff! Das Leben ist kein rosa Plüsch-Enten-Teich. There are always people with different opinion - the trick is, not to ignore stuff, and maybe even learn from them. But, probably you will find another way to defame me her.. - Frunsi
47
[0] [2010-07-01 00:38:20] BJB

Go read Douglas Crockford's "Javascript: The Good Parts"


48
[0] [2010-07-01 00:43:15] Frunsi

Most common error or mis-use: You did not understood the language!

JavaScript may be seen as a language with a lot of gotchas (as is the case for most of us).

But it may also be seen as a language which is just different than most other languages we know!

Most importantly, the scope is different than what most people expect! A JavaScript programmer should start with learning how the scope works in JS. Then everything is enlightened.


49
[0] [2010-07-01 00:52:39] STW

The most common error, imo? Using JavaScript as a scripting language and not a Functional language.

Personally I stepped away from JS while I learned OO development, and returning to it with the awareness of what a Functional language is, and how it can be used, made me furious to find so many entrants avoiding the functional aspect of it (which is a very significant portion!).

So, while your question might be better asked as "how do I avoid syntactical erros and their effects?", just remember that not all errors are caught by a compiler/parser/interpreter--perhaps you can avoid some of these errors by focuses on how to best leverage the language.


50
[0] [2010-07-01 00:56:51] thomasrutter

Mistake: relying on the existence of some global object property without testing to see if it exists first.

Not all browsers/environments implement the same API.

With things like window.alert() you can get away with using it, because it's pretty safe that it will always be supported. Other things, however, are not so widely supported, like (window.)document.all, window.returnValue, etc.


51
[0] [2010-07-01 01:38:28] jgemedina

What about using duck typing or feature detection, this is very helpful when insterested in handling something depending on the browser.

for example:

if(object.property)

or:

if(object.function) / if(object.prototype.member)

not taking this into consideration might cause some headaches sometimes, so this would be a way to avoid it and a good practice.


52
[0] [2010-10-12 16:51:32] Majid Fouladpour

Expecting this to pass a reference to the a clicked when used in

<a href="javascript:somefunc(this);">do something</a>

As Josh Stodola [1] explains in this answer [2], the correct way to pass a reference in such cases is to use onclick instead of href:

<a href="javascript:void(0);" onclick="somefunc(this);">do something</a>
[1] http://stackoverflow.com/users/54420/josh-stodola
[2] http://stackoverflow.com/questions/3915483/how-do-you-find-which-link-was-clicked/3915591#3915591

53
[-2] [2009-07-29 05:33:07] Luca Matteis

Expanding native JavaScript objects should be avoided, although I don't consider it a mistake if used in affordable situations.

Array.prototype.func = function(){ ... };

(1) Could you explain why this is a mistake? - Shog9
(1) I disagree. I.e. I needed to extend Date object in order to add custom formatting methods. - Sorantis
54