Hacker News new | ask | show | jobs
by oneeyedpigeon 4177 days ago
Your comment might be useful or interesting if you explained which WTF moments affected you in particular, or even just which other languages you've used. As it is, it's not adding much to the conversation which is why you've been downvoted.
5 comments

Most of these WTF examples basically boil down to JS doing type coercion willy-nilly. This 'feature' makes writing conditionals slightly shorter, in exchange for introducing the possibility of massive bugs everywhere in your code at any moment. Seriously, f* JS type coercion.

The other misfeature I hate is that accessing undefined properties doesn't raise an error (then, but you can be sure it will make your program blow up a bit later).

Typescript helps to solve both.

I'm actually trying to write a book about that myself. It's called "JavaScript es basura caliente: Learning JavaScript in Anger".

The goal of the book is not to rag on JS. That's not new or really interesting in its own right. The goal is to walk people through the oddities of the language such as identity loss when passing a function from an object to something else (the good old this == window rather than self).

There are interesting, and annoying, things about JS that are non-obvious to people from a different language like Java or C#. There are other issues like testing and package management that are either assumed or glossed over. The JS community knows about them. Unfortunately for most of us, the responses to the language's weakness and ecosystem strengths are dispersed through the interblogs.

In fact from personal use of JS and some research on the book, I'm moving to a functional approach with JS. OO in Ecma5 is a pain. Pure (or Clojure like) functional can work with a bit of help from Underscore. That pardigm seems to fit the mentality of JS better too.

https://leanpub.com/javascriptesbasuracaliente

Some WTF moments in Javascript, courtesy of Gary Bernhardt:

    var foo = ["10", "10", "10"];
    foo.map(parseInt);
    // Returns [ 10, NaN, 2 ]

    [] + [] // ""
    [] + {} // {}
    {} + [] // 0
    {} + {} // NaN

    var a = {};
    a[[]] = 2;
    alert(a[""]); // alerts 2

    alert(Array(16).join("wat" - 1) + " Batman!");
Press F12 and use the Console to verify these if you're skeptical.
While these are WTF moments, when is anyone actually going to run [] + [] in a real project? The map to parseInt is the only one that's even close to something you'd actually write.
Writing literal [] + []? No.

Writing x + y where x and y are both arguments to a function, and some call site was passed an (empty?) array of integers instead of an integer? Believable.

So the real problem is passing wrong parameters to a function? Sounds like you should swap to something like TypeScript for strict typing then.

Or you know, stop acting like JavaScript is unique in that improper function calling breaks your code.

I can't believe in 2015 there are still people who follow the "JavaScript equalities are WTF" mentality. If you are running into equality operator problems in JS, you are probably going to run into a myriad of problems in any language.

Except in any decent language, however typed, improper function calling creates errors.

I can't believe in 2015 there are still people who follow the "invalid input should produce invalid output" mentality.

I've been writing JS professionally for, what, a decade now - and I've never once had this issue.
It's not about this causing issues IMO. It's just.. why? Why would '+' not be commutative? Why not throw an error? What is the use-case for "adding" '[]' and '{}'?

Or, put another way: why would a programmer want to have this "feature" instead of being notified: "hey, you're adding '[]' and '{}', that doesn't make any sense, fix that!"

Sure you can work with a language like that. But it sure doesn't feel like somebody thought all of this this through.

The first one is easy to understand though.

parseInt takes two arguments: $thing_to_change and $radix; map iterates over an array and feeds it $value and $index. You're getting parseInt("10", 0); parseInt("10", 1) and parseInt("10", 2);

The fix would be to partially apply parseInt with your defined radix;

  var foo = ["10", "10", "10"];
  var base10 = function(val){ 
      return parseInt(val, 10); 
  };
  x = foo.map(base10)
  [10, 10, 10]
A lot of the ones he presented are easy to understand. It's still a WTF when you run into it though.
All you have done is used a function without understanding what it was doing, or reading the documentation. Most JS developers know how parseInt works, and even if they run into this problem, would quickly discover the cause. I don't see how this is a flaw of Javascript; it could happen to a developer of any language, if their strategy is 'well, it looks like it'll work'.
> All you have done is used a function without understanding what it was doing, or reading the documentation

These aren't my examples. I haven't done anything. I credited the person who provided them: Gary Bernhardt.

https://www.destroyallsoftware.com/talks/wat

https://www.destroyallsoftware.com/talks/the-birth-and-death...

Next time before you make an accusation, reread the post before pressing the reply button.

Nope. Behavior should be pretty straight-forward, I shouldn't have to load up the docs to convert something to an integer.
I guess my question is: what would have to change, in the last example, to make it not WTF to you? To me it seems pretty straight-forward what is happening.
These are pretty bad examples. I can safely say that I have never run into these in the wild, or seen any other developer run into these.
I know what the batman example gives but I don't get how it's a WTF?

I assume the expected output is "wa" but why should a string less an integer produce that?

There is no expected output. It doesn't make sense to subtract the value 1 from the string "wat". But Javascript will cast both of them to numbers, then try to subtract 1 from NaN. However, if you do "wat" + 1, Javascript will cast both of them to strings, and append "1" to "wat".

It's not just the odd behavior, but the inconsistency.

Ok that makes a bit more sense. I didn't even think about how it would be if you tried to add them.

I like javascript but I don't do anything so complicated (or maybe not the right types of things) that I run into many of these situations.

No, it produces NaN (Not-a-Number), and then repeats it in a string 16 times. The WTF is that NaN can be concatenated to strings as "NaN".
NaN is passed to Array.prototype.join() as the separator to join strings with, so it gets coerced to String ("NaN"). It's deliberately working backward from the behaviour of Array.prototype.join() to create a contrived example for giggles, not a WTF.

It's no more a WTF than this, which follows the same principle: https://gist.github.com/insin/1183916

Oh, I understand that. I was more trying to explain why someone might think it was a WTF.

And I'm pretty sure your example returns the decimal 15. Comma operator returns the last element in the list, and parseInt will truncate strings with non-number-like text to the number-like part. Here, the number-like part is a hexadecimal code, triggering another feature of parseInt that it can figure out the radix on the fly.

Here you go: http://wtfjs.com
You didn't link to it and it's still pretty irrelevant to the original discussion.