This site uses 3rd-party cookies for targeted advertising. If you do not agree to this, then please leave this site now. Otherwise please click on "Ok" to continue.
Ok
 
 

Why I sometimes hate JavaScript

27-Feb-2015

Maybe it's because I'm relatively new to JavaScript. Maybe I'm just getting old. But yesterday evening JavaScript really pissed me off.

I was refactoring some code. After the change it didn't work as intended. There was no error-message, the code just didn't do what it was supposed to do. At first I thought it was because of some floating-point problem, but it wasn't.

It was of course entirely my own mistake. But it was a mistake which would have created a compiler-error or warning in other languages.

It took me about 30 minutes before I finally found it. Let's see if you can spot the error here. And before you judge me for not seeing it sooner, keep in mind that you know beforehand that there is an error to find here.

result.rankingValue =
    phraseValue( result, queryData ) +
    noSpacesPhraseValue( result, queryData ) +
    keywordInResultValue( result, queryData ) +
    hiddenKeywordInResultValue( result, queryData ) +
    keywordPositionValue( result, queryData ) +
    isDomainRootValue( result, queryData )
    urlStartWithWWWValue( result, queryData ) +
    urlLengthValue( result, queryData ) +
    pathElementsValue( result, queryData ) +
    backLinksValue( result, queryData ) +
    domainRankValue( result, queryData );

You will have to look very closely to see that in the middle of this code, the line that starts with isDomainRootValue is missing the plus-sign at the end. Which of course meant that the results of all the remaining function-calls were simply ignored instead of being added up.

Simple mistake. Easy to overlook. Hard to find. I wish there would have been an error-message. Would have saved me half an hour.

Comments:

Author: (Unknown)
2015-02-27 10:16 UTC
 

That's why I use an editor with in-build jslint support. If I run the above exemple through jslint.org, it gives me the following message:

Expected ';' and instead saw 'urlStartWithWWWValue'.

isDomainRootValue(result, queryData)

line 9 character 5
Expected 'urlStartWithWWWValue' at column 1, not column 5.

urlStartWithWWWValue(result, queryData) +

Author: (Unknown)
2015-02-27 10:21 UTC
 

I am pretty sure a jshint or some other tool would have picked up the mistake?

Author: (Unknown)
2015-02-27 12:00 UTC
 

Don't blame javascript. It's your fault.

You can format this way:

result.rankingValue = phraseValue( result, queryData )
    + noSpacesPhraseValue( result, queryData )
    + keywordInResultValue( result, queryData )
    + hiddenKeywordInResultValue( result, queryData )
    + keywordPositionValue( result, queryData )
    + isDomainRootValue( result, queryData )
      urlStartWithWWWValue( result, queryData ) // see the error?
    + urlLengthValue( result, queryData )
    + pathElementsValue( result, queryData )
    + backLinksValue( result, queryData )
    + domainRankValue( result, queryData );

or even better:

var values = [
    phraseValue,
    noSpacesPhraseValue,
    keywordInResultValue,
    hiddenKeywordInResultValue,
    keywordPositionValue,
    isDomainRootValue,
    urlStartWithWWWValue,
    urlLengthValue,
    pathElementsValue,
    backLinksValue,
    domainRankValue ];

result.rankingValue = values.reduce(function(acc, fn) {
    return acc + fn(result, queryData);
}, 0);

Author: (Unknown)
2015-02-27 12:04 UTC
 

You might try TypeScript or my own LiteScript https://github.com/luciotato/LiteScript

Author: (Unknown)
2015-02-27 12:36 UTC
 

Have alook here https://www.dartlang.org/

Author: (Unknown)
2015-02-27 12:45 UTC
 

That's why you should organise your code in blocks like that

tableHeadings = "<thead><tr>";
tableHeadings += "<th>Description</th>";
tableHeadings += "<th>Price</th>";
tableHeadings += "<th></th>";
tableHeadings += "</tr></thead>";

In that code you can not miss +

Author: (Unknown)
2015-02-27 12:52 UTC
 

jslint

but javascript is pain indeed

Author: (Unknown)
2015-02-27 12:55 UTC
 

Use jshint at least.

check your code here to immediately see errors.

jshint is not as much IN TO YOUR FACE as jslint.

http://jshint.com/

Where I work, I simply can't use jslint. Sometimes you can't.

That's when jshint is awesome.

Author: (Unknown)
2015-02-27 13:02 UTC
 

Whenever I have highly repetitive code like this, I make it more readable by tab-indenting the repetitive part, ie., ( result, queryData ), so it lines up. Makes it more readable and the missing + sign is real obvious.

Author: (Unknown)
2015-02-27 13:08 UTC
 

It's not your fault. The decision to make semicolons optional was a bad one.

If you have to resort to external tools, different ways to write code or to derivative languages, then the language itself is broken.

JavaScript has its faults, but with some proper tooling, it's a nice and powerful language.

Author: (Unknown)
2015-02-27 13:19 UTC
 

I agree, JavaScript is a dynamic language, and as such allows too much freedom. As proposed by the other comments, JSHint can help a lot. Trying your code, this is the notification message that I receive. (WebStorm is a great tool to mitigate these problems and work quite safely with javascript).

******** JSHint ******

This inspection reports JavaScript statements which are not terminated by a semicolon. While line-breaks may be used instead of semicolons to terminate JavaScript statements, some coding styles prefer the semicolon for consistency with the other languages.

Author: (Unknown)
2015-02-27 13:22 UTC
 

All guys saying that it's your fault are bullshit loaded dumpsters!

It's not working. There is no error. How it can be your fault?

Your coding style does not matter at this point.

Author: (Unknown)
2015-02-27 13:29 UTC
 

That's a horribly written statement, you deserved to debug that painfully.

Author: (Unknown)
2015-02-27 13:29 UTC
 

That code would earn a -2 from me, in part because it would be extremely hard to maintain. It falls foul of my "code that splits over one line invites bugs" rule.

You appear to be building a string by calling a series of functions over the same input data. Is this really the best way to organise this? Why not have each function return the modified string so you can chain them at least?

Author: Michael Schöbel
2015-02-27 13:30 UTC
 

I'm not building a string. I'm adding up floating-point values.

Author: (Unknown)
2015-02-27 13:34 UTC
 

The problem is to do with the editor not with the language

the editor should have told you that you have 2 statements while you thought you had 1

ciao

lorenzo

Author: (Unknown)
2015-02-27 13:34 UTC
 

Copipasted this to my editor. Get two errors:

"Missing semicolon" on isDomainRootValue line,

"Expected an assignment of function call and instead saw an expression" on last line.

Javascript development can't be productive without usefull tools like jshint.

Author: (Unknown)
2015-02-27 13:43 UTC
 

dump vim. get WebStorm.

30 minutes of wasted time === IDE would have paid for itself instantly.

Author: (Unknown)
2015-02-27 13:46 UTC
 

also my editor said: "Unterminated statement" and underlined the offending part of the code.

unless you are autistic or OCD'd, stop writing code in pico or notepad pretending you can spot all the typos.

Why I'm even reading this...

Author: (Unknown)
2015-02-27 13:47 UTC
 

2 seconds here...

Author: (Unknown)
2015-02-27 13:48 UTC
 

CoffeeScript solves some of the problems like that... and then adds some new ones :)

-- yosh from KeMu

Author: (Unknown)
2015-02-27 13:54 UTC
 

I strongly disagree with the people saying things like "it's not javascript's fault, it's your fault". Javascript's automatic semicolon insertion is the "feature" that is to blame.

I too learned that you need to lint your javascript code the hard way. BTW I prefer 'jshint' to 'jslint'.

Author: (Unknown)
2015-02-27 14:00 UTC
 

To be frank you knew it too, why else wouldn't it work :D

You just didn't accept it :)

Author: (Unknown)
2015-02-27 14:05 UTC
 

Dude, you are a mediocre programmer. Now go back to Java.

Author: Michael Schöbel
2015-02-27 14:06 UTC
 

FWIW I hate Java a LOT more than JavaScript.

But my favorite is still Pascal.

Author: (Unknown)
2015-02-27 14:08 UTC
 

Some already mentioned this, but JSHint catches this with 2 warnings.

In Sublime text 3, you can have inline warnings and as-you-type linting with the sublimelinter jshint plugin:

https://github.com/SublimeLinter/SublimeLinter-jshint

It saves so much time when developing, and feels a bit like using an IDE.

Author: (Unknown)
2015-02-27 14:08 UTC
 

spotted in one second...

Author: (Unknown)
2015-02-27 14:12 UTC
 

I am the only one who spot that bug in 2-3 seconds?

Author: (Unknown)
2015-02-27 14:19 UTC
 

You can also use join() on an array when concating lots of strings. It's kind of less error prone and automatically coerces the values to string.

result.rankingValue = [
    phraseValue( result, queryData ),
    noSpacesPhraseValue( result, queryData ),
    keywordInResultValue( result, queryData ),
    hiddenKeywordInResultValue( result, queryData ),
    keywordPositionValue( result, queryData ),
    isDomainRootValue( result, queryData ),
    urlStartWithWWWValue( result, queryData ),
    urlLengthValue( result, queryData ),
    pathElementsValue( result, queryData ),
    backLinksValue( result, queryData ),
    domainRankValue( result, queryData )
].join('')

In your case if the first couple of functions returned a number or boolean, they would be summed instead of concated, not giving you the expected result, e.g.:

> true + 10 + " result"
11 result

> [true,10," result"].join('')
true10 result

Author: (Unknown)
2015-02-27 14:25 UTC
 

hmm i saw that pretty quickly

Author: Michael Schöbel
2015-02-27 14:26 UTC
 

As I mentioned above this is not string-concatenation, but adding up numbers.

Author: (Unknown)
2015-02-27 14:28 UTC
 

Use strict mode for more errors :

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode

Author: (Unknown)
2015-02-27 14:29 UTC
 

With code like this it's better to line up as many things into columns as you can. So, break lines before the operators, line up function parameters, etc.

Author: Michael Schöbel
2015-02-27 14:30 UTC
 

I did use strict-mode. I always do. Didn't help.

Author: (Unknown)
2015-02-27 14:41 UTC
 

I guess you were either tired or not getting help from the right tools.

To minimise this I use Sublime Text with the Railscasts Extended theme.

As it's colouring specifically annoying chars such as "+" it took me literally 2 seconds to spot this.

I would advise you to play around with your favorite editor and change the default syntax colouration, this stuff is not only for eye candy, it really is a great help when dealing with human error.

And I must admit that I make many mistakes like yours when coding.

Just take it easy, it's not like it's your first time, and it will certainly won't be your last. :)

Author: (Unknown)
2015-02-27 14:41 UTC
 

Just blame the language. Its not you, You are a special snowflake.

Author: (Unknown)
2015-02-27 16:14 UTC
 

Also, a similar one: http://mihai.bazon.net/blog/javascript-wat

Author: (Unknown)
2015-02-27 17:44 UTC
 

Yes, automatic semicolon insertion is the worst!

Author: (Unknown)
2015-02-27 19:20 UTC
 

I also put the + at the beginning of each line instead of at the end as another comment mentioned. Looks nicer and it's easier to catch those errors.

That said, don't be catching simple errors like this on your own. Make your computer do it. Use a linter.

Author: (Unknown)
2015-02-27 20:59 UTC
 

please tell me that code snippet isn't in production anywhere.

Author: Michael Schöbel
2015-02-27 21:05 UTC
 

It's not in production. But in about a week or two it will be. Apart from the bug - which is now fixed of course - I have no intention of changing it.

Author: (Unknown)
2015-02-28 10:51 UTC
 

If the code were being tested, say with Mocha or Jasmine, it might have been easier to catch the error.

Author: Michael Schöbel
2015-02-28 11:18 UTC
 

I have unit tests for Mocha. That's how I knew that there was an error. Actually finding it was the problem.

Author: (Unknown)
2015-03-01 18:26 UTC
 

For Javascript/Nodejs I suggest to use a good IDE like WebStorm (https://www.jetbrains.com/webstorm/ or the IntelliJ IDEA Community edition from the same company: https://www.jetbrains.com/idea/download/ with plugins)

Author: (Unknown)
2015-03-02 08:45 UTC
 

If you used JSHint runner you would get the detailed error.

You want to comment on this blog-post? If yes, then simply enter your comment in the field below and click on "Submit".

Comments are moderated at the moment thanks to some $%&# who thought it would be funny to post total nonsense here.

 


Back to the Homepage

A Programmer's Diary