
WTFJS – a list of funny and tricky JavaScript examples - PleaseHelpMe
https://github.com/denysdovhan/wtfjs
======
vmasto
> If you are a professional developer, you can consider these examples as a
> great resource for interview questions and quizzes for newcomers in your
> company

No, do not consider these examples as a "great" resource for interview
questions. They are nothing more than tricks and hacks abusing the bad aspects
of the language and anyone who includes them in an interview has failed in
screening JavaScript developers, at least in my book.

A JS developer should understand that JavaScript has some flawed, unfixable
core concepts and educate themselves on how to avoid them, not use them in
actual production code or memorize every coercion scenario.

Some simple rules:

1\. Always use referential equality checks (triple equal `===`). In idiomatic
JS you can also use double equality only when explicitly checking against
undefined or null (foo == null). It's the only use of abstract equality that I
find acceptable.

2\. Learn how the `this` execution context works. Kyle Simpson explains it
very well in YDKJS ([https://github.com/getify/You-Dont-Know-
JS/blob/master/this%...](https://github.com/getify/You-Dont-Know-
JS/blob/master/this%20%26%20object%20prototypes/ch2.md)). There are four
simple rules that matter and are straightforward to grasp.

3\. Familiarize yourself with how type coercion works in JS but avoid it. The
spec is quite easy to follow in this matter and follows very specific,
documented rules. e.g.:

[https://www.ecma-
international.org/ecma-262/8.0/index.html#s...](https://www.ecma-
international.org/ecma-262/8.0/index.html#sec-additive-operators)
[https://www.ecma-
international.org/ecma-262/8.0/index.html#s...](https://www.ecma-
international.org/ecma-262/8.0/index.html#sec-abstract-equality-comparison)

Use strictly as reference.

4\. Stop using plain ES5, the language currently is ES2017. ES2015 and beyond
provide modern constructs that make most of ES5's weirdness obsolete. For
example, never use `var` anymore, `const` and `let` are superior initializers.

By following the above rules a JS developer should be fine in 99% of cases, in
my experience. Yes, JavaScript will possibly implode on you on the rest 1%,
but I'd be hard pressed to find a (similarly popular) language that doesn't.
If one finds that to be unacceptable, enabling types via TypeScript or Flow
should make their life even easier.

~~~
aaron-lebo
_1\. Always use referential equality checks (triple equal `===`). In idiomatic
JS you can also use double equality only when explicitly checking against
undefined or null (foo == null). It 's the only use of abstract equality that
I find acceptable._

I've found this advice in guides and in codebases, but it seems unnecessary to
me. The vast majority of equality checks are of the if (str == 'str') or if (n
== 0) type. It's rare that you are actually comparing two objects of different
types and when you are it's kind of nice to see === and know, otherwise it's
just kinda ugly (kinda like const in languages, but we don't gotta hash that
out here). There is a debate like this in the lisp community over eql and
such. Similarly, isn't (foo == null) redundant? In most cases if (!foo) is
what you are interested in and it's cleaner.

Is this incorrect? Would be cool to have it clarified. Have never actually run
into a bug due to it, so not sure if the limitations of == are mitigated
though coding style or what.

But in total agreement otherwise. Modern JS is really good, it's as productive
as anything else, expressive, and once you know the quirks they are easy to
avoid. Where JS has problems is inexperienced devs where they can code with
var and for (var ...) monstrosities that date back to like 1996.

~~~
nolok
> Is this incorrect?

Yes it is. The reason for the deep equality check is not so much that you want
the check on type, but because this way you avoid the entire giant class of
errors caused by type coercion, just like in PHP. Think things like:

    
    
      function check_user_id(user_id) { return user_id == 1; }
      check_user_id('1 error detected');
    

It's obvious when you see the exemples, and is usually a bug somewhere due to
a missing check, but in language such as this it can often causes deep errors
yet stay unseen for months.

There is a reason why strict type hinting has become a most-wanted (and now
beloved) feature of PHP, and of JS through language such as TypeScript: most
of the time, you don't really care like you said if it's '1' or 1, but because
it's supposed to be a number anyway it makes no sense to not force it to be
one or error out.

In other words, it's better to trade "I don't want deep equality check most of
the time" with "I don't want lax equality most of time".

~~~
twiss
To be fair, your example returns false in JavaScript, unlike in PHP.

------
twiss
_We can fix this with Greater than or equal operator ( >=):_

 _3 > 2 >= 1 // true_

What? No, JavaScript doesn't have chained comparison operators, as the author
seems to know but not explain. Overall this list is pretty misleading and
uninteresting IMHO.

------
uwu
> Object.create(Array).length === 1 //true

it bothers me how the examples are often misleading or just misusing language
features but people who don't know the language will gladly agree with them
and have their "js sucks" belief reinforced

~~~
tambourine_man
Agreed, although some things like:

    
    
      NaN === NaN // -> false 
    

Are pretty f*&^%$ up, no matter how you look at them

Edit: well, apparently there is a non f&^%$ up way to look at it:
[https://news.ycombinator.com/item?id=14891810](https://news.ycombinator.com/item?id=14891810)

~~~
xyclos
NaN is meant to represent a non-sensical mathematical operation (like divide
by 0). One non-sensical mathematical operation is not the same as some other
non-sensical mathematical operation (1/0 !== Infinity/Infinity)

~~~
justinpombrio
Nor is it the same as the same non-sensical mathematical operator :-)

1/0 !== 1/0

~~~
tambourine_man
That's mad. In JS, 1/0 is Infinity, not Undefined. And Infinity is not equal
to itself.

------
b0rsuk

      $python
      Python 2.7.9 (default, Jun 29 2016, 13:08:31) 
      [GCC 4.9.2] on linux2
      >>> True + True
      2
      >>>
    

okay...

    
    
      python3
      Python 3.4.2 (default, Oct  8 2014, 10:45:20) 
      [GCC 4.9.1] on linux
      Type "help", "copyright", "credits" or "license" for more   information.
      >>> True + True
      2
      >>>
    

I'm going to try this in Rust.

~~~
achanda358
That's probably because

    
    
        $ python
        >>> int(True)
        1
        >>> int(False)
        0

~~~
masklinn
No, that's because (for historical reasons of booleans having only been added
in Python 2.3[0])

    
    
        >>> issubclass(bool, int)
        True
        >>> True == 1
        True
        >>> False == 0
        True
    

[0]
[https://www.python.org/dev/peps/pep-0285/](https://www.python.org/dev/peps/pep-0285/)

------
nthcolumn
From a few years back but made me laugh a lot:
[https://www.destroyallsoftware.com/talks/wat](https://www.destroyallsoftware.com/talks/wat)

------
deelowe
Such blatant misuse of the language in these examples. Not sure what to think.
It seems like the author has a good understanding of JS, but then goes out of
the way to purposefully misrepresent things to construct strawmen simply to
then tear them down. If someone comes across this without being familiar with
JS, they could very easily be misled.

As a comparison, how many WTF C++ examples could be constructed if people
misused arrays, pointers, bitwise comparators, oeprator overloads, templates,
etc... to create nonsensical operations?

~~~
pvg
There is plenty of verbiage at the top explaining the motivation (some of it
even under a big heading 'Motivation').

These aren't misrepresentations (let alone 'strawmen', whatever that might
mean in this context) and there is no 'tearing down' at all, just links to
explanations.

------
LoSboccacc
NaN != NaN should be obvious, otherwise Math.sqrt(-1) == 0/0

------
brudgers
More WTF, [https://wtfjs.com/](https://wtfjs.com/)

------
gattilorenz

      (typeof (new (class { class () {} }))) // -> 'object'
    
      It seems like we're declaring a class inside of class. Should be and error, however, we get an 'object' string. 
      Explanation:
      Since ECMAScript 5 era, keywords are allowed as property names.
    

Can anyone explain why allowing keywords as property names seemed a good idea?
To me it creates a lot of potential for confusion without providing enough
benefits, but I'd like to be... enlightened

~~~
masklinn
Because they found out they had little reason not to, and it can be convenient
e.g. in Python when messing around with metaprogramming you have to use `cls`
or `kls` or `klass` rather than the obvious `class` as a local variable name,
just because keywords can't be used in other context. It's even more annoying
in JS as e.g. a property named `class` is very common in DOM contexts.

------
Tade0
From now on I'm going to include at least one of these in each interview I'll
be conducting - for extra points of course.

Anyway a lot of these examples can be explained if you know how type coercion
works in JS and are aware what the `valueOf` method exists for.

Here's a nice write-up about this mechanism: [http://2ality.com/2011/12/fake-
operator-overloading.html](http://2ality.com/2011/12/fake-operator-
overloading.html)

~~~
vmasto
> From now on I'm going to include at least one of these in each interview
> I'll be conducting - for extra points of course.

There's absolutely 0 benefit from an engineering standpoint in having type
coercion memorized in JavaScript.

I'd personally immediately terminate every interview that posed such questions
({} + [] + '' or whatever).

I mean no offense, but I'd ask you to reconsider. People who ask trick/puzzle
questions and hacks in interviews do not understand (or haven't thought deeply
enough) how to properly screen JS developers which eventually goes through to
the team itself. There are at least a dozen more interesting topics to
question on if you want to assign extra points than useless stuff that should
never be into production in the first place.

~~~
Tade0
> There's absolutely 0 benefit from an engineering standpoint in having type
> coercion memorized in JavaScript.

I would argue there is one:

tl;dr: Planning for the worst from the people who tend to generate code which
is, in one word, bad but which they managed to push to production.

===

When you know you're going to work with people who are not familiar with this
concept, but still managed to shoehorn some code that looks a lot like these
examples.

Recent case: A local front-end server for development purposes and an SPA with
a login form. The server checks for certain, hard-coded credentials and if
they match lets the user through. Problem was, if you didn't get them right at
the first try the proper credentials stopped working until you reloaded the
page.

How did that happen? There's an extra field in the form that is initialized to
an empty string, but if the form is reset(on login failure) it is set to null,
while the server checks for: field == '', because somebody assumed this would
be enough.

Null is falsy, but it's not _equal_ to other falsy values. People who don't
know that are usually left scratching their heads.

===

Anyway no offense taken and I'd be happy to hear some suggestions on how I
could improve this process. Usually when I ask a "trick" question I give a
warning beforehand indicating, that this is not something which is going to
affect their score negatively. I found that normally people _like_ this part
and are often curious about the proper answer.

EDIT: One thing I would like to note is that I conduct interviews for the
project which I'm currently in, so I'm going to suffer the consequences of any
bad decisions on my part eventually.

------
justinpombrio
My favorite:

    
    
        x = "053"
        y = 50
        z = "40"
    
        x > y
        // -> true
        y > z
        // -> true
        z > x
        // -> true

~~~
toomanybeersies
To be fair, that's the case in Ruby and C as well, and probably other
languages. It's because 0 coerces it into an octal.

I actually had a bug because of this a while ago at work.

------
tomxor
Except for "Precision of 0.1 + 0.2" which all programmers should know is a
floating point fraction arithmetic limitation, not a JavaScript issue.

------
johnhenry
This is really useful because of the attached explanations.

------
ndz
That's one of proofs that JavaScript is an evil without TypeScript especially
in inexperienced hands :)

------
sAbakumoff
It's interesting to see that a lot of people make fun of JS, publish articles
on how weird it could be, receive a ton of likes, but still it's the most
popular programming language at the moment. It's like Stockholm Syndrome we
developed with time!

~~~
Ygg2
> It's like Stockholm Syndrome we developed with time!

It's easy to use and widely available. Give me example of another computer
language that is installed on every computer with internet access.

The base language isn't that bad, it's just that some bad initial decisions
and backwards compatibility forced some really sharp paper cuts, most of you
can avoid.

Does this means that One True JS Programmer can write flawless JS Code? No,
but in practice you don't have to write flawless JS Code.

~~~
sAbakumoff
I agree that most of "very strange things" about JS can be avoided. 90% of
these "look, js is weird" articles are quite useless as they make use of very
artificial scenarios.

~~~
b0rsuk
These are merely extreme cases. Javascript is full of less mind-boggling
inconveniences. It's not like they only kept the really bad features for
laughs and fixed the rest.

~~~
sAbakumoff
Agree. "this" thing in JS can be really inconvenient for beginners.

