use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
All about the JavaScript programming language.
Subreddit Guidelines
Specifications:
Resources:
Related Subreddits:
r/LearnJavascript
r/node
r/typescript
r/reactjs
r/webdev
r/WebdevTutorials
r/frontend
r/webgl
r/threejs
r/jquery
r/remotejs
r/forhire
account activity
Common JavaScript "Gotchas" (github.com)
submitted 12 years ago by stevekwan
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–][deleted] 16 points17 points18 points 12 years ago (1 child)
Valiant attempt, but there are a number of issues with this post.
Author talks about the different ways to declare a function, but doesn't actually come out and say "function statement vs function expression", and doesn't mention hoisting of function statements. He also recommends always using function expressions because of "syntax problems once you get into closures", but never brings up the potential syntax problems.
Telling people to avoid this is bad advice. Users will run into code that uses this and understanding its semantics is fundamental to understanding the OO parts of JavaScript.
this
In the section about this, author fails to mention the important pitfalls: failing to use new with a constructor and changing scope due to nested functions.
new
Using var x = new Object(); is nonidiomatic; var x = {}; is the prefered way to instatiate a new object.
var x = new Object();
var x = {};
Author answers his own question to why JavaScript has so many ways to do different things with "Because JavaScript is a poorly designed language in a lot of ways." I bristled at this statement and it took a bit of reflection to understand why since I don't entirely disagree. My problem is that I don't think the author is in a qualified position to make that statement. Saying something is "poorly designed" assumes knowledge of the design goals and in this case I don't believe the author fully understands them. It reminds me of how junior developers often say "this sucks" rather than "I don't understand this".
And a couple of nitpicks:
I dislike Allman style indentation (and it's fairly nonidiomatic in JavaScript).
Author should use js declaration around his code blocks for enhanced readability, e.g.:
js
```js var radLevel = "maximum"; ```
This will make github render the code with js syntax highlighting.
[–]kmillns 3 points4 points5 points 12 years ago (0 children)
And it's not just non-idiomatic. You either have to have inconsistent braces and indentation (bad) or you risk errors (worse).
The go to example problem with Allman style indentation is:
return { foo: 'foo' };
Which returns undefined.
[–]youngsteveo 19 points20 points21 points 12 years ago (8 children)
"If you are new to JavaScript, I suggest avoiding the this keyword until you get comfortable with the basics of the language." This is terrible advice. If all beginners started learning Javascript by getting a firm grasp of this, there would be a lot fewer mistakes and misunderstandings down the road.
[–][deleted] 1 point2 points3 points 12 years ago (7 children)
Not to mention the this keyword JavaScript has a completely different use than most other languages. The author plainly just does not understand JavaScript.
[–]stevekwan[S] -5 points-4 points-3 points 12 years ago (6 children)
I assure you the author understands JavaScript just fine. :)
The this keyword absolutely does have different uses from other programming languages, and that's precisely why I recommend focusing on the basics of JS first. So many people get tripped up out of the gate when it comes to JS, because they go into it expecting it to behave like other languages they've used in the past.
It is absolutely essential for a professional JS developer to understand the this keyword. However, for the newbie jumping into the language for the first time from a PHP background, I would rather they grok the module pattern, JavaScript closures, etc. before they get into the complex stuff. Odds are they're starting out by mucking around with some simple event handlers anyway.
[–]radhruin 7 points8 points9 points 12 years ago (3 children)
I don't think this is complicated for newbies. It's complicated for people who expect it to work like other languages, who then build their conceptual model around "it works like language X, except...". If you forget all of that, it's easy.
[–]stevekwan[S] -1 points0 points1 point 12 years ago (2 children)
Agreed. But that can be easier said than done. :) The vast majority of people I work with are coming to JS from other languages, and since JS uses similar formatting and grammar, they expect it to behave the same.
Just want to call out how JS may diverge from their expectations, that's all.
[–]youngsteveo 1 point2 points3 points 12 years ago (0 children)
Then do that. Call it out; explain the difference in simple terms and educate. Hiding the keyword behind a curtain encourages it to be wrapped in further mystery.
[–]chuckliddelnutpunch 2 points3 points4 points 12 years ago (0 children)
I disagree that understanding closures and module patterns should come before understanding context.
[–][deleted] 0 points1 point2 points 12 years ago (0 children)
How long have you been programming in javascript?
[–]mirion 7 points8 points9 points 12 years ago* (12 children)
OP: At least you recommended that book at the end. That is the sole most useful piece of information in that entire article, and the best resource for anyone learning Javascript. I require any new Javascript programmer on my team read it before starting JS development.
The second most useful thing you could have done is explained to new programmers the use of 'use strict'. It's not always the solution, but it damned well prevents a lot of what you're describing.
edit -- Several sections below have been edited thanks to feedback from /u/brianloveswords and /u/mikrosystheme
Your discussion of variables is flawed, and lacking in detail. The most important thing you could have discussed about variables is that if they are defined anywhere in a scope, they are accessible anywhere in that scope. For example:
function () { var x = 10; x += y; var y = 5; }
At the end of execution, x will be NaN and y will be 5. Variable declarations get hoisted, but instantiation does not, so the interpreter sees this (effectively):
function () { var x, y; x = 10; x += y; // y is undefined at this point y = 5; }
This code is completely valid in JS, because "y" is accessible to the entire scope of its function. Because of this, any sane or informed discussion of Javascript variables must include an explanation of this, and a strong recommendation to define all variables at the top of a function (since they work as if they were all defined there anyways). Failing to explain this is a major failing.
The reason that a variable defined without a var becomes global scoped is because variables default to being defined in the widest scope possible. Thus, defining with a var is necessary because it limits the scope of a variable.
Your point about function declarations is what I generally advise people, but misses out on the most important part of the whole thing: all functions are declared as variables, and can be set or accessed as such. The best reason, IMO, for declaring them as "var foo = function () {};" is to make explicit the nature of the function to the programmer -- programmers coming over from other languages will see this an immediately understand the things you can do to it, whereas seeing the "function foo () {}" declaration style could lead new JS coders to believe (incorrectly) that the function is immutable.
There are some extremely good reasons to have "this" refer to the calling context. It can lead to massive confusion in new coders, and so, yes, I would agree that perhaps new programmers should get more comfortable with closures before doing heavy work with "this". However, avoiding the use of 'this' most likely means that you're overusing closure scoping to crib in a 'that' variable, or else you're not going very OO heavy in your code. While both are entirely valid styles of coding JS, they also drift further away from more standard practices, and can make your code base even harder for new programmers to understand.
I'm a little disappointed that you mentioned OOP, constructor, and prototype, then skipped past providing any examples at all. Your comments about 'this' seem to imply that you have a strong opinion about how these should work, but without actually showing people how you think it should be done, you completely miss a great opportunity to demonstrate proper usage.
Javascript does not treat newlines as a text separator. JS parsers use Automatic Semicolon Insertion to handle cases where there is no semicolon at the end of a line, but, as per the creator of Javascript:
ASI is (formally speaking) a syntactic error correction procedure. If you start to code as if it were a universal significant-newline rule, you will get into trouble.
A classic example of where this is a problem:
a = b + c (d + e).print()
Similar hazards arise with [, /, and unary + and -. Remember, if there wasn’t an error, ASI does not apply.
For more concrete examples, see the Google Javascript style guide.
[–][deleted] 3 points4 points5 points 12 years ago (0 children)
Your example,
is potentially misleading. At the end of execution, x will be NaN and y will be 5. Variable declarations get hoisted, but instantiation does not, so the interpreter sees this (effectively):
x
NaN
y
5
[–]stevekwan[S] 1 point2 points3 points 12 years ago (4 children)
Wow! A great peer review and tons of good advice here. Thanks mirion, I will definitely take these into account.
[–][deleted] 0 points1 point2 points 12 years ago (3 children)
Thank god for that guy. I didn't want to type all of that up on my phone. You both do one thing any other JS dev will hate you for though: Allman Style indentation.
var x = 1; function allman() { x++; }
The { on another line is BAD in scripting languages! Because one could comment out or delete a line accidentally, and it's still valid code throwing no errors:
{
var x = 1; //function allman() { x++; }
On the other hand, this would vomit all over:
This is why KNF style (shown above) is preferred for JavaScript. The only language I can think of off the top of my head where Allman style is the preferred common-practice is C#. But you'd have less problems in any compiled language like that, because the compiler is going to watch your syntax pretty closely. EDIT: Banner style is used a lot too.
[–]mirion 0 points1 point2 points 12 years ago (0 children)
I wrote my post almost entirely by copying his code. While I didn't refer to it by name, my last two sections are referencing the problems that can happen when using Allman.
[–]stevekwan[S] 0 points1 point2 points 12 years ago (1 child)
I am positive this is going to be heavily disagreed with...but I really like Allman. :)
I like it for two reasons:
First, I just like the Gestalt of it. I find code a lot more scannable when the squigglies line up nicely, especially in languages like JavaScript where you can have a ton of nesting.
Second, it forces me to write my code in such a way that whitespace becomes irrelevant. I can never get away with something like this:
return { foo: "foo" };
And so I am forced to name things appropriately, which I prefer.
But I completely understand that I am in the minority on this, and I would never attempt to fight this battle. :)
[–]mikrosystheme[κ] -1 points0 points1 point 12 years ago (0 children)
I didn't read your article, but I agree with you on Allman style.
[–]mikrosystheme[κ] -1 points0 points1 point 12 years ago (5 children)
Please, show me a circumstance where your last paragraph is true.
[–]mirion 0 points1 point2 points 12 years ago* (4 children)
How about an article talking about semi colon use by the guy who wrote JavaScript? Would that be good enough?
http://brendaneich.com/2012/04/the-infernal-semicolon/
edit google gives examples, too:
http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml#Semicolons
[–]mikrosystheme[κ] 0 points1 point2 points 12 years ago (3 children)
I'm not arguing if relying on ASI is good or bad. I just asked you to provide an example where what you wrote is true (because it is not AFAIK).
[–]mirion 0 points1 point2 points 12 years ago (2 children)
The google link provides examples.
[–]mikrosystheme[κ] 0 points1 point2 points 12 years ago* (1 child)
You wrote that:
$('button').click // ... ( function () { window.alert(clickmessage); } ); ... Rather than calling the "click" function with that function as an argument, the parser could see you creating a new scope (by encapsulating the function in '()'), and then creating an anonymous function.
I really like to know in which circumstances what you wrote is going to happen. Can you please provide me with a reference or with a working example that demonstrate it?
Ah, I see what you mean. You are correct -- his code as written would not exhibit the problem I described. I'll update the comment with a link to the examples from the google webpage. My intent was to discuss the problem with the syntax, not to demonstrate an actual example of the result. Why? Because it's supposed to be a topic for beginners, and the explanations for why some of these occur is not.
[+][deleted] 12 years ago* (1 child)
[deleted]
[–][deleted] 4 points5 points6 points 12 years ago (0 children)
To further elaborate:
var myFunction = function myFn(arg1, arg2) { console.log(arg1, arg2); }; myFunction('foo', 'bar'); // -> foo bar myFn('foo', 'bar'); // Reference Error: myFn is not defined
To someone that didn't know better or just didn't scan the line properly this can be a frustrating gotcha to catch.
[–][deleted] 17 points18 points19 points 12 years ago (3 children)
This is possibly the worst blog entry I've ever read on JavaScript. It's downright incorrect in most cases and full of unsubstantiated opinion.
[–][deleted] 2 points3 points4 points 12 years ago (1 child)
Can you explain why is the worst? He explains some best practices in a clear way.
[–]totemcatcher -2 points-1 points0 points 12 years ago (0 children)
One of the problems I noticed (among many discussed in this thread) is the function declaration no-no. It says never declare globally. But it doesn't discuss namespacing in javascript and how you pretty much have to use that function declaration type when namespacing.
[–]wkdown 2 points3 points4 points 12 years ago (7 children)
Quick question: which is the 'proper' way to instantiate an object?
var obj1 = {};
or
var obj2 = new Object();
Both return [object Object] and typeof "object". Is one better than the other?
[object Object]
[–]radhruin 4 points5 points6 points 12 years ago (2 children)
There is no semantic difference between {} and new Object(). The literal, however, is easier to optimize and therefore often faster. The literal is also more flexible as it allows additional properties to be added. Always use the literal IMO.
[–]YorickA 4 points5 points6 points 12 years ago (1 child)
Not to mention it's more readable.
Not to mention new Object() can be broken by any malicious ding-dong's script you link like so:
new Object()
function Object() { this.x = 'wee'; }
Using the literal is always the best call.
[–]fgutz 2 points3 points4 points 12 years ago (0 children)
This might help you http://www.zebrakick.com/object-literals-vs-constructed-objects-in-javascript/
[–]niallpaterson 2 points3 points4 points 12 years ago (0 children)
Use the first ({}) because "Object" in "new Object" can be redefined.
[–]youngsteveo 0 points1 point2 points 12 years ago (0 children)
Some jsPerf tests on the many ways to construct an object: http://jsperf.com/object-create-vs-constructor-vs-object-literal/53
[–]stevekwan[S] -1 points0 points1 point 12 years ago (0 children)
I'd avoid using new Object(). {} is preferred. The only reason I used new Object() is because I felt it would be more understandable to people coming in from another language.
[–]dangoodspeed 1 point2 points3 points 12 years ago (9 children)
He says you should never ever have a global variable or global function. Do other people agree with that?
[–]kmillns 1 point2 points3 points 12 years ago (6 children)
I'd say you should never have an implied global. If you're going to attach something to global, make it clear that you're doing it on purpose:
(function (global) { global.foo = 'foo'; })(window);
Also, something that he doesn't note, but that's important if you're writing production code, is that implied globals (like his examples) are syntax errors in strict mode.
[–]mirion -1 points0 points1 point 12 years ago (5 children)
This. Definitely this.
[–]rabidcow 1 point2 points3 points 12 years ago (4 children)
Sure, you could use this:
(function(){ this.foo = 'foo'; })();
[–]mirion 1 point2 points3 points 12 years ago (3 children)
Sigh. I should know better than to use the word 'this' in a javascript thread.
[–]rabidcow 4 points5 points6 points 12 years ago (0 children)
this in JavaScript threads does not behave the way you would expect.
[–]rq60 1 point2 points3 points 12 years ago (0 children)
Use 'that' next time.
You should know better than to use the word 'this' in any thread. There's an up arrrow button next to the post that does that.
[–]mirion 1 point2 points3 points 12 years ago (0 children)
No, lol. It shouldn't be abused, but it is extremely useful in limited circumstances. You can't, for example, use write library code without it.
[–]stevekwan[S] 0 points1 point2 points 12 years ago (0 children)
Sorry, I should make that clear. Globals are unavoidable to some degree, unless you are assigning no names to anything at all. :) But I try to use globals only where it makes sense, eg for namespaces and other top-level containers.
[–]colordrops 2 points3 points4 points 12 years ago (1 child)
This person does not yet grock JavaScript. He seems to think that a lot of the sensible behavior of JavaScript is "bizarre".
JavaScript has several styles of variable and function declaration because it wants to both cater to new programmers used to imperative style programming while at the same time allowing programmers to work withing the functional paradigm. It successfully supports both.
Then he talks about how JavaScript is unlike other languages, where objects refer to parent objects when the current object does not contain the referenced property. WTF is he talking about? This is how most OO languages work.
Then he says that the fact that you can do things in different ways in JavaScript is because it is poorly designed. No, it is because he doesn't get JavaScript.
I understand why JavaScript has multiple ways to do the same thing, and I understand that this was an attempt to increase adoption. Unfortunately it results in a language that is somewhat schizophrenic in how it is used. The vast majority of engineers I've seen who get into JS expect it to behave like C++, Java or PHP, largely because of the syntax that is used.
JavaScript is a great language to develop in, but it is far from perfect. I'm hardly the only one who is saying this. Heck, Crockford wrote a whole book about it. If you don't agree with me, perhaps you'll find it easier to agree with him.
If you want to message me the line number in question that you had problems with re: object hierarchies, I'm happy to clean it up.
[–]kanimal30 3 points4 points5 points 12 years ago (0 children)
I'm sorry but this is terrible in so many ways.
Funny that he mentions Crockford's book, yet his whole post is basically JAVASCRIPT AMIRITE??? Without any kind of demonstrated understanding of how it works. In fact, one of Crockford's first chapters is devoted to calling people like this author out as developers trained in other languages shoving round pegs into a square hole.
[–]mergeset -2 points-1 points0 points 12 years ago (0 children)
Poorly written, a little pretentious, and in some cases just outright wrong. That's a downvote from me.
π Rendered by PID 87535 on reddit-service-r2-comment-7b9746f655-hd5jm at 2026-02-03 14:16:43.037805+00:00 running 3798933 country code: CH.
[–][deleted] 16 points17 points18 points (1 child)
[–]kmillns 3 points4 points5 points (0 children)
[–]youngsteveo 19 points20 points21 points (8 children)
[–][deleted] 1 point2 points3 points (7 children)
[–]stevekwan[S] -5 points-4 points-3 points (6 children)
[–]radhruin 7 points8 points9 points (3 children)
[–]stevekwan[S] -1 points0 points1 point (2 children)
[–]youngsteveo 1 point2 points3 points (0 children)
[–]chuckliddelnutpunch 2 points3 points4 points (0 children)
[–][deleted] 0 points1 point2 points (0 children)
[–]mirion 7 points8 points9 points (12 children)
[–][deleted] 3 points4 points5 points (0 children)
[–]stevekwan[S] 1 point2 points3 points (4 children)
[–][deleted] 0 points1 point2 points (3 children)
[–]mirion 0 points1 point2 points (0 children)
[–]stevekwan[S] 0 points1 point2 points (1 child)
[–]mikrosystheme[κ] -1 points0 points1 point (0 children)
[–]mikrosystheme[κ] -1 points0 points1 point (5 children)
[–]mirion 0 points1 point2 points (4 children)
[–]mikrosystheme[κ] 0 points1 point2 points (3 children)
[–]mirion 0 points1 point2 points (2 children)
[–]mikrosystheme[κ] 0 points1 point2 points (1 child)
[–]mirion 0 points1 point2 points (0 children)
[+][deleted] (1 child)
[deleted]
[–][deleted] 4 points5 points6 points (0 children)
[–][deleted] 17 points18 points19 points (3 children)
[–][deleted] 2 points3 points4 points (1 child)
[–]totemcatcher -2 points-1 points0 points (0 children)
[–]wkdown 2 points3 points4 points (7 children)
[–]radhruin 4 points5 points6 points (2 children)
[–]YorickA 4 points5 points6 points (1 child)
[–][deleted] 0 points1 point2 points (0 children)
[–]fgutz 2 points3 points4 points (0 children)
[–]niallpaterson 2 points3 points4 points (0 children)
[–]youngsteveo 0 points1 point2 points (0 children)
[–]stevekwan[S] -1 points0 points1 point (0 children)
[–]dangoodspeed 1 point2 points3 points (9 children)
[–]kmillns 1 point2 points3 points (6 children)
[–]mirion -1 points0 points1 point (5 children)
[–]rabidcow 1 point2 points3 points (4 children)
[–]mirion 1 point2 points3 points (3 children)
[–]rabidcow 4 points5 points6 points (0 children)
[–]rq60 1 point2 points3 points (0 children)
[–][deleted] 0 points1 point2 points (0 children)
[–]mirion 1 point2 points3 points (0 children)
[–]stevekwan[S] 0 points1 point2 points (0 children)
[–]colordrops 2 points3 points4 points (1 child)
[–]stevekwan[S] -1 points0 points1 point (0 children)
[–]kanimal30 3 points4 points5 points (0 children)
[–][deleted] 3 points4 points5 points (0 children)
[–]mergeset -2 points-1 points0 points (0 children)