While some folk will argue that verbose code aids readability, I think almost the opposite, and in this post I’m going to list some basic tips for minimising redundant clutter in your code. JavaScript is a fun language at its core — it’s worth learning the tiny details.
I hope this post is useful to someone. I wrote it not for beginners (although it will be helpful to them), but for all those people writing JavaScript on a daily basis yet haven’t been afforded the time/motivation to get to know the language properly.
new Object()
Nope, don’t do this:
var o = new Object(); |
Or any of this:
var a = new Array(); var b = new Object(); var c = new RegExp("1(.)3"); |
Do this instead:
var a = []; var b = {}; var c = /1(.)3/; |
Array literal, object literal, regular expression literal. They rock. There’s usually no need to use the constructor functions when literals are available (please see the note below though).
Note: There are situations when calling Array
or RegExp
directly can be useful. In such situations, you needn’t bother with the new
operator. Array(1,2,3)
will produce the same as new Array(1,2,3)
. Calling RegExp
directly can be useful for dynamically building a regular expression from various strings.
Calling a constructor
If you’re not passing any arguments then the parenthesis are not required. E.g.
var a = new Animal(); |
… and this becomes:
var a = new Animal; |
Petty, perhaps. Still worth knowing though.
var;var;var
Quick and easy. Less of this:
var fun = 123; var tun = 456; var run = 789; |
And more of this:
var fun = 123, tun = 456, run = 789; |
This is why you should use a tab width of FOUR (or 4 spaces).
Undefined & Null
The following is universally true in JavaScript (assuming undefined
hasn’t been mutilated):
undefined == null |
“So what?”, you say? Well, it means you can replace this:
if (foo === undefined || foo === null) { //... } |
… With this:
if (foo == null) { //... } |
If something is ==
to null
then it is either null
or undefined
. Those are the only possible values.
Returning undefined
Not returning something from a function is the same as returning undefined, so you may as well not bother explicitly returning undefined:
function a() {} function b() { return; } function c() { return undefined; } a() === b(); // true b() === c(); // true |
Note: you should be careful with the undefined
value as it can be changed. E.g. You can do undefined = true
beforehand. The universe would shatter if you did that though, so please don’t. Many libraries declare an empty (undefined) variable in an enclosed scope, which provides a real undefined
:
(function(){ // My private scope. They can't see me in here. var undef; undef; // => definitely undefined }()); |
Or, more succinctly:
(function(undef){ undef; // => definitely undefined }()); // <- not passing anything in! |
Empty array values
This is entirely legal in JavaScript:
var a = [,,,'foo']; a[3]; // => "foo" |
One potential use-case of this was discussed in my recent post, `match.()` trick.
Less blocks, more expressions
I’m sure we’ve all seen something like this before:
function validateFoo(foo) { var regexResult = /^foo+$/.test(foo); if (regexResult) { return true; } return false; } |
A cleaner and more sensible solution is this:
function validateFoo(foo) { return /^foo+$/.test(foo); } |
No fussing with if
statements and multiple returns. You can do everything within a single return statement.
Another example. We want to create a function that logs a name, specified by the arguments forename
and surname
, but if these arguments aren’t passed then the function should use the default values, “Bob” and “Smith”, respectively:
function printName(forename, surname) { if (forename == null || forename == "") { forename = 'Bob'; } if (surname == null || surname == "") { surname = 'Smith'; } console.log(forename + ' ' + surname); } |
This can be condensed to:
function printName(forename, surname) { forename = forename || 'Bob'; surname = surname || 'Smith'; console.log(forename + ' ' + surname); } |
Here, we’re using the logical OR operator (||
) to provide a default value (right hand side) if the left hand side evaluates to false. Values that evaluate to false (i.e. “falsey”) are: An empty string (""
), null
, undefined
, 0
and false
.
So, this:
forename = forename || 'Bob' |
… is essentially saying: if forename
is a truthy value, then assign forename
to forename
(in other words: don’t do anything), but if it is a falsey value (e.g. an empty string), then assign the string "Bob"
to forename
.
So, our new printName
function will behave like so:
// -- Logged -- printName(); // Bob Smith printName(0, 0); // Bob Smith printName(false, null); // Bob Smith printName('James'); // James Smith printName('', 'Jones'); // Bob Jones printName('Bill', 'Jones'); // Bill Jones |
Part 1 [OVER]
That’s it for today. There may be a part two soon enough, depending on how useful this is to readers. I know many of you have surpassed this stage of learning, so sorry for boring you.
Recommended viewing/reading
Seriously, if you’re writing JavaScript as part of your job then you definitely owe it to future maintainers of your code to learning JS properly.
EDIT: Crockford links don’t work. The entire video can be seen on youtube instead.
- Douglas Crockford: “The JavaScript Programming Language”/1 of 4
- Douglas Crockford: “The JavaScript Programming Language”/2 of 4
- Douglas Crockford: “The JavaScript Programming Language”/3 of 4
- Douglas Crockford: “The JavaScript Programming Language”/4 of 4
- Bonus: Intro to JS & the DOM
Thanks for reading! Please share your thoughts with me on Twitter. Have a great day!
Sorry! The Crockford links don’t work. Here’s the entire thing on Youtube: http://www.youtube.com/watch?v=v2ifWcnQs6M
Thanks James! very useful please carry on!!! looking forward to part two 😉
I enjoyed this reading eating an ice-cream, what a combination. This is all the basics a JS Programmer should know, thanks for making that clear & easy a very good resume!!! Obvious I want part 2!!
You rocks!!
Wow, I could hardly disagree more with most of your post.
While I do agree in principle, that once you are skilled in a language, it is fun to write code that is elegant, this totally ignores the reality of programming.
Most professional programmers have to switch not only between different projects – current and old – but, most importantly, between different programming languages. And while many of us have mastered a language close to perfection, the reality of being a programmer just doesn’t allow us to stick to the one language we like.
So when after a month of fighting against someone else’s messed up Perl code followed by a month of both Zend and Zope programming, I have to work on your Javascript project, I might just not remember the subtleties of JS.
And a method doSomethingToObjectOfTypeAlphaSoThatItBecomesAnObjectOfTypeBeta($obj) might just be easier to grasp than a2b($o).
I think you should also encourage people to pick one type of quote and stick with it.
Aside from that, great post 🙂
Have you tried Coffeescript? Curious to hear your take on that.
That is good stuff, nice little tricks will definitely speed code up. Thanks
Excellent write-up!
One minor suggestion though — in your conditional assignment example, you’re re-assigning even if it’s not needed:
It’s more efficient to do this (although JSLint complains about it):
There’s a performance comparison, and a lovely write-up on the subject.
Get rid of the assignment and write less code (since that’s the subject at hand):
Thanks for the comments.
@Peter, I was trying to demo the assignment though. Obviously, in reality, it’s not required.
@Mathias, I was going to show that… thought it would be too much at this point.
@Rick, good point!
@Michael,
a2b
isn’t the only alternative to that ridiculously long name, you know… Also, I don’t know about you, but I like to work towards mastering all the tools I use. It makes perfect sense. Also, when I write JS code, I think it’s okay to assume that the coder reading it knows JavaScript. Assuming anything else would have me writing code accommodating the most basic level of understanding. JavaScript is a tool, like all languages. If you don’t want to learn it then just say so…Loving it! Waiting for part 2 … ^^
i find IIFEs more readable with bangs (and they’re shorter to boot). So instead of
you’d use
another advantage is that you don’t introduce mis-execution when concatenating several files that use this pattern.
You could also get `undefined` back with `undefined = void 0` if you need to 🙂
Don’t forget to mention this one:
This article is so awesome, I am shooting rainbow beams out of my eyes.
Nice hints. My personal favourite condenser & clarifier is using nested ternary operators to define a variable
so instead of
You can have
Excellent post and well worth a read! Thanks for putting this together. You can never forget these little bits of knowledge that we often neglect as our code becomes more intense. Sometimes less is more1
Thanks James! I’m also looking forward for part 2! ^_^
Nice read. Since you’re listing the falsey values, I’d mention that NaN is one too 🙂
I know it’s not directly related, but I’ve worked with developers of one language that pretty much write using the same syntax in JavaScript (over bloating when not needed). This article is a nice read too: How Good C# Habits can Encourage Bad JavaScript Habits.
@Mathias Handy. I hadn’t thought of that before. Looking at jsPerf there seems to be an oddness for older browsers using it (missing results?) – but it’s nice to think differently about things. Thanks for the links.
loved it. more stuff like this please
I think I agree with everything except “Undefined & null”.
Whilst
undefined == null
most of the time (as you pointed out), by encouraging developers to ignore the subtle difference between the two values I think you encourage lazy development (as opposed to a neat code refinement). It is moresemanticallycorrect to check for both cases, which I think is more important than saving a few keystrokes or bytes of source code.If I see the following:
if (foo == null)
I always have to stop and figure out whether the other developer meantif (foo === null || foo === undefined)
or whether they meantif (foo === null)
.Given that n00b developers learn from the l33t, I think we have a responsibility to distinguish between an often misunderstood/misused pair of values.
I use this to default stuff all the time:
@Marcus JavaScript lacks a conditional assignment operator, so that wouldn’t work.
You’re right of course, I was stuck in AS3 mode. My apologies.
Great article! Something else you may want to point out about not using the ‘new’ keyword is that this really blows away the use of typeof since everything created that way will be noted as an object.
var myStringObject = new String(“abc”); //typeof === object
var myString = “abc”; //typeof === string
There is also a difference between using the ‘new’ keyword and not. When you use ‘new’ the resulting object is a complex object (or reference object) whereas when you omit the ‘new’ it essentially creates a primitive value.
This means big things when you talk about comparing values since complex objects are compared by reference where as primitive values are compared by value.
Seriously though… Great article! 😉
@Vernon, good point about differences between
new String
and"..."
, but it is important to note that the differences between literal values and values instantiated vianew ...
is only relevant for primatives like Number and String, not RegExp, Array or Object.Three different ways with the same outcome on each line:
There’s a slight difference with RegExp and
/.../
in some implementations. More here..@Jon, very good point. I guess in that case it would pay to be explicit, but it’s still good to know about
undefined == null
.Nice stuff! It’s good to see points i didn’t know 🙂
Also don’t forget:
typeof Array //object
and the workaround from Douglas Crockford for this and some more:
http://javascript.crockford.com/remedial.html
Finally, please Second Part hehe!
Fran
@fmvilas
This reminds me of Christian Heilmann’s http://www.wait-till-i.com/2007/11/27/javascript-shortcut-notations-that-shouldnt-be-black-magic-to-the-average-developer/
Very very helpful stuff. Really appreciate it and can’t wait to see what’s in store for Part 2…
Simplify, rinse and repeat! Nice write up James!
You’re mentioning that there are situations where using Array() (as opposed to using a literal) can be useful, but I can’t think of any. Can you give an example?
Small tips but can make a huge difference. Great stuff. Parts 2, 3, 4.. etc please.
This is good stuff! It should be required reading for everyone.
I don’t agree with the “null” and “undefined” munging though. “null” is not the same thing as undefined- treating them that will lead you down a dark path. And even though jslint goes overboard in some areas, I think use of the “==” operator should be avoided unless it really makes sense and shortens code (e.g. to operate on numeric data received as a string without explicitly converting it). It’s just too easy to end up with something working wrong in a difficult to track down way because of things like “0” which evaluates true.
And for undefined I think it’s better just to test for undefined instead of mucking around with something you “define” as undefined:
It always works. No questions. If you have to do it a lot want something briefer, then make a function to do the same. But you probably shouldn’t have to test for undefined very often if you’re writing good code.
I also strongly agree with the comment about being consistent with single and double quotes. I prefer single – not sure why, but it just seems easier to read in javascript. Single quotes for JS literals, double quotes for HTML attributes.
Finally I don’t agree with using this construct (per one of the comments):
The only advantage is performance. It’s slightly longer, and is much less intuitive to read. Anything that does an assignment inside an expression is dicey in the first place, because it smells like a mistake.
While you could get used to it, will other people? Given that my computer was able to do this operation 600 million times in one second using the SLOW version, I think it is safe to say that the 20% performance boost is probably inconsequential in most situations.
@Jamie, I don’t agree that
is less intuitive to read. You have a point there that an assigment inside a statement isn’t great, but it’s unambiguous, even if you don’t know Javascript (as long as you recognize ‘=’ as an assignment).
On the other hand,
can be confusing, because there are lots of languages where logical operators return Booleans, in which case this line wouldn’t make any sense. So, for people coming from PHP, for instance, this is rather counterintuitive.
Your point about the boolean operator being confusing is valid. I actually remember that confusing me for a while. (That article someone linked to about good c# habits resulting in bad javascript habits was my bible at the time, coming from a primarily c# background 🙂
But after you get used to it, it’s pretty fundamental javascript – it’s part of learning the operators, and it gets used very often. I guess you could argue the same for your construct, but I think that having an assignment result from an inner expression is not good practice in any language. It’s probably pretty harmless in this context but the advantages seem minor.
It reminds me actually of the most basic “terse javascript” principle which nobody mentioned, surprisingly, especially in the context of testing for null & undefined. I’ve never worried much about testing for both null & undefined before, since what you usually want is just to test for basic truthiness:
That bothered me for months when I started doing a lot of JS. Now I just wish I could do it in C# instead of all this IsNullOrEmpty business for strings, or having to test explicitly for null objects!
super excited to see what’s next!!
Very nice post. Please carry on good work.
Very well written article. I will try and use some of these examples in my code I am writing today.
BTW, very cool background for your page.
@James that’s right. That’s my bad for not thinking through my comment completely before I wrote it. 😉
forename = forename || ‘Bob’ is why I really wish there were a ||= operator in JavaScript:
forename ||= ‘Bob’;
Thanks, very helpful even for a beginner. I look forward to reading more of your posts
Some of these should come with more of a warning. For example:
var fun = 123,
tun = 456,
run = 789;
That’s great until the function gets changed and run is no longer needed. So let’s delete that line.
var fun = 123,
tun = 456,
And hello bug! Sure it’s minor. It’s so minor it’s easy to overlook. But it can’t happen with the var on every line method. I used to use this exact concept and stopped for this very reason. In fact, the more terse you make your code, the more likely things like this are going to creep in.
Anyway, I disagree with you about readability, but there is certainly a place for terseness in programming. There are definitely some things worth considering here. We just need to remember that one man’s terseness is another man’s bug factory.
I have accumulated 14 different languages (3 of them at expert level) in my 35 years of programming for a living. I am now adding JavaScript (started a new job a few months ago) to this list and welcome articles like this.
@James: Keep up the good work. I look forward to seeing the other parts.
@commentor’s: Anything that reduces the amount of data/code that you have to upload to the ‘client’ should be grabbed with both hands.
@RobertW.M: As James stated in the intro, this is not about reducing the amount of data that has to be sent to the client, but about readability. Those few bytes saved by using James’ tips are nothing compared to the benefit of minification in production, which most sites don’t even bother to do.
That said, I don’t agree with all of the advice:
is arguably less readable than
usefull,hope the part 2
Some good reminders, especially the null vs undefined.. But with the use of minification, these are all rather moot. I’m Not a fan of multi-var declarations. And Four
Spaces is NOT a set convention, ie google, and many others clearly enforces a two space convention for better column widths and terminal viewing.
@Gregory Nicholas – the point isn’t about saving a few bytes, it’s about writing expressive code.
Some of this, like combining vars, is coming from Douglas Crockford’s evangelism. While not everyone agrees with him on every point, he usually has a rational reason, and it almost always has to do with writing better code.
In the case of using a single var statement per scope, it’s because variable declarations are hoisted into a scope. That means any block acts as if all vars were created at the beginning of the scope. Using a single var statement expresses this fact much more clearly than not doing so. For example:
is perfectly legal, and “b” is defined only within the function scope. But what value would a casual reader expect “b” to have a the end? A lot of people would say “20” because this writing seems to imply that inside the conditional, b is scoped. And indeed with most languages, it would be.
In reality, this is how Javascript interprets this:
It is much more clear what the intent was, and you avoid making mistakes due to confusion as a result of late declarations.
So the advice to use a single ‘var’ statement is not simply to save a few bytes, it is primarily to encourage you to write code that expresses the way javascript defines and scopes variables.
@Jamie, your example doesn’t explain anything. You could just as easily avoid that problem by doing this:
function test(foo) {
var bar = 10;
var b = 20;
if (foo == bar) {
b = 30;
…
}
console.log(b);
}
(Sorry, I can’t figure out how to format it all nice and pretty.)
@ScottM – you’re right. The idea is that by having a single var statement, you absolutely eliminate the possibility of a late declaration. If you get in the habit of always using a single var statement (and letting tools like jslint confirm that for you), you eliminate the possibility of writing code that could fall into this trap. There’s absolutely nothing wrong with doing it that way either, it’s more about habits.
Like I said not everyone agrees with this all of the Crockford stuff, but the idea is to enforce habits that avoid Javascript’s pitfalls. I kind of like this one, personally, and I definitely think you shouldn’t have var declarations anywhere but the top of a scope. But nothing wrong with that way either.
@Jamie, I get your point now. I do agree that it’s better to have var declarations at the top of the scope. But as I said in my first comment (before the one to you), if all the variables are being declared in one place, I see little reason to put them all in one var statement and a good reason not to. I just don’t think it aids readability in the slightest.
I think it comes down to preference. Crockford’s argument is that this forces you into a habit that is failsafe and easy to verify. But your point is also valid. I’m used to it – I don’t think it impairs readability, but again, that’s just beacause I’ve gotten used to it. In the end I see nothing wrong with doing it either way, and the point made before about edits potentially causing syntax errors is also something that’s not insignificant either.
At the end of the day I think what’s worth reinforcing is that you really, really should have no var declarations after your first line of non-declaration code. If this construct helps you get in that habit, great.
Part of this could also have to do with the linting tools. Jslint and jshint check (optionally) that you have only a single var statement. I am not sure if they also can/do check for out-of-sequence vars off the top of my head, or just for more than one var. That would seem to be all that’s important, so maybe this notion grew alongside the validation tools, just because it’s easier to spot & verify.
nice and clear tips.
I’m a sucker for this kind of detailing… It’s all about elegance! looking forward to part two 🙂
Very useful indeed! I love simple articles like these that are easy to read and packed with info. Thanks!
sweet!
short and clean, i’m sending it to a lot of friends 😀
I did not know you could exclude the parenthesis when using “new”. However one point I would like to add is that you cannot call a method directly from your new object when you do this, eg:
And just for personal preference I also only use 1 var at the top but formatted using tabs, so it appears like a declaration block (I use jslint alot):
Btw, I like your background. It gives a subtle illusion of distance 🙂
Glad to see (and hope everyone reads) the additional comments about null vs. undefined vs. ‘undefined’ vs. ”.
The differences could be considered “semantic”. But there are bug and performance considerations for each evaluation type.
@Rick Waldron: +1 to the single-vs-double quotes too. Too much time is wasted tracking down JS issues caused by closing js expressions with the wrong quote — or inside DOM object events (onclick=”doThisWith(“that”);”). Our code review policy includes single quotes for JS, double for HTML attributes, always.
Thanks for the post and the excellent comments that have resulted.
The combining
var
technique can lead to some very unreadable code and easy-to-make mistakes:I have seen numerous times when a person—who is new to the code base—comes in and accidentally ends a line with a semicolon instead of a comma making all consecutive declarations implicitly global. Oops.
When formatting a single var statement, I like to put the comma on the next line. It gives a visual queue that it’s all one statement. Also makes it more apparent to the dev that you shouldn’t bang on a semi-colon, I read from left to right so I’m more likely to pick up the comma.
Something along the lines of:
@Anton, if you popped in a semi-colon half way along, wouldn’t the interpreter would throw an error rather than cause the consecutive declarations to be global.
@Rob,
No, you can it see for yourself here: http://jsfiddle.net/VXdQv/1/. Omitting
var
simply creates an implicit global variable.@Anton you are correct – but anyone who codes any substantial javascript without using a syntax checking tool like jslint/jshint is nuts. This shouldn’t be an issue.
Hi @Anton and @Jamie,
Describing two slightly different scenarios; If the value is unknown and you only declare the variable and don’t instantiate it in the
var
statement then an error will be thrown.This throws an error (unless local4 and local5 have already been instantiated elsewhere within the global space):
As opposed to the following code which doesn’t fail, but has globals.
Here’s the fiddle http://jsfiddle.net/VXdQv/3/
Sorry I missed your point to begin with : )
All valid points you have made there James, except there are times in my coding when I have to do the opposite of what you claim I should not do.
If you read plenty of books on the subject of JavaScript, all the authors never use should / should not, they simply explain the language, and leave it to the programmer to make his choice on syntax.
Remember JS is not like C where the coder has no choice but to organize his code religiously.
JS – It’s a do what the fuck you like language. That is, if you can even call it a language at all.
s/Less blocks/Fewer blocks/. Good example, though. I’ve reduced the line count in some source files by >50% by collapsing all the useless if(…) return true; else return false; garbage (which in turn makes other redundant lines more apparent).
Something that might throw people off, just because undefined == null doesn’t mean you can do something like:
if(something == null) {}
because you will get an error saying that “something” is undefined.
you still have to do:
if(typeof something == ‘undefine’) {}