

Oddities about JavaScript - fogus
http://www.smashingmagazine.com/2011/05/30/10-oddities-and-secrets-about-javascript/

======
unwind
That NaN (not a number) doesn't compare equal to itself is not, in my opinion,
a JavaScript oddity. NaN behaves like that according to the IEEE 754, and
Wikipedia suggests that using the fact that x == x returns false is a way to
test if x is NaN (<http://en.wikipedia.org/wiki/NaN>).

~~~
dexen
Nothing odd about it, it's the good old math at work.

Is (3 / 0) == (4 / 0)?

Is even (3 / 0) == (3 / 0)?

EDIT:

also, see [1] on what becomes when dividing both sides of equation by zero and
assuming equality still holds. Essentially, both sides become NaNs and
everything is possible -- up to and including 1 == 2. Now that'd would be
_odd_ , should it happen in your program.

[1]
[http://en.wikipedia.org/wiki/Invalid_proof#All_numbers_equal...](http://en.wikipedia.org/wiki/Invalid_proof#All_numbers_equal_all_other_numbers)

~~~
jerf
The problem with this line of logic is that == is not equality. Two things
being equal means they are actually the same thing and there aren't two things
there at all, just one thing expressed two different ways. == is a binary
relation [1]. In the context of that binary relation, if you made NaN == NaN
it wouldn't really affect anything mathematically, because you already can't
equationally reason on the basis of that binary relation, so there is no
equational reasoning to become corrupted by accepting a contradiction.

[1]: <http://en.wikipedia.org/wiki/Binary_relation>

~~~
dexen
_> (...)there aren't two things there at all, just one thing expressed two
different ways (...)_

I have to respectully disagree with you :-)

Consider for a moment ``3 + 0''. That expression (those three tokens) denote
something we can talk and reason about. Now the important point: not because
of some inherent property of the notation itself, but because we, the people,
agreed what we mean by that expression.

Contrast that with expression ``3 / 0'' -- which does not denote anything.
Maybe, just maybe, there _is_ something usefull that stems from division by
zero, but! so far, we have not agreed upon what would be denoted by division
by zero. We haven't agreed upon anything this expression would mean. It
denotes no single thing, and neither a (nonempty) set of things. Of course, we
have to somehow describe the fact of ``having nothing to say'' -- we use `NaN'
-- but that's not a number symbol, that's a meta-symbol. Means, ``nothing to
see there, my dear CPU, please move along''.

Note also, how in SQL, the following does _not_ hold true: NULL = NULL. In
SQL, `NULL' doesn't stand for something, but for no thing at all. And whaddya
know, division by zero yields NULL in SQL.

* * *

As for the equality itself (as opposed to assignment), so far we, the
programmers, have only one common use for it -- checking whether data from
some source ``equals'' data from another source. There are three common ways
of doing that:

0) pointer equality. Fastest, simpliest, but won't suffice in some programming
languages. Thing is, one kind of languages keep just single copy of all the
same values (say, every variable that holds string "foobar" points to the same
memory cell), but others do not, and here you need one of the two following
ways.

1) value equality (== in JS): whether the two expressions ``evaluate'' to the
same value. This has two downsides: is generally slower (the overhead of
runtime evaluation), and often is governed by twisted rules reagarding type
coercion. For example, in PHP, the following holds: 0 == "1". Fun fact to know
and tell: those twisted rules stem from the language creators' desire to make
programming easier.

2) type-and-value equality (=== in JS): this straightens some ofthe twisted
rules of 1), due to comparing data types first (instead of prerforming type
coercion), but otherwise does the same thing: compares value. May often be
faster and also simplier to grasp, but also may blow up when you mix up data
with different types. Which nb. is easy to overlook when data comes from data
sources having different semantics or idioms.

To put 1) and 2) in another way, those operations compare two values by their
properties. Yet the NaN doesn't have properties to speak of, because it is not
a value in the first palce. The operation of comparing is thus not well
defined for NaN. Oops? :-)

~~~
jerf
"I have to respectully disagree with you :-)"

You said this, but you never seemed to get around to an actual point of
disagreement that I could see.

I'm not sure you realized that I was talking about _math_ equality. In math,
there is no distinct "3" vs. "3 + 0". We can indeed talk about how they are
different tokens but there's no second "3". There's just the one in
conventional systems that most people have heard of, expressable in a
countably infinite number of ways (without getting crazy).s

(Yes, I know some of the other ones. That's why I said "conventional systems",
after all.)

Math equality not being the same as programmer equality was my entire point.
Thanks for elaborating on that theme, I guess? And given that it isn't the
same thing, we aren't particularly constrained in how we use our programmer
equality except by practical considerations. If we want NaN to == NaN and not
=== NaN, it's just a matter of making the programming runtime do it. Or vice
versa. Or we can simply crash, which actually given how frequently people
_actually_ want NaN in Javascript is probably actually the choice I would
choose. We aren't constrained by how continuous mathematicians of a certain
school think our numbers work, because as programmers we _never_ work with
those numbers. We have completely different things going on. Actually if you
operate on the assumption that your computer numbers are like mathematician
numbers you will be in for nothing but pain on both sides.

------
stanleydrew
Section 7 is so completely wrong:

    
    
        var someVar = 'hello';
        setTimeout((function() { alert(someVar); })(someVar), 1000);
        var someVar = 'goodbye';
    

This won't do what he thinks it's going to do. Instead of alerting 'hello'
after 1 second (after the value has been changed to 'goodbye') it alerts
'hello' immediately and does nothing after 1 second. Perhaps he meant
something like:

    
    
        var someVar = 'hello';
        setTimeout(
            (function(innerVar) {
                return function() { alert(innerVar); };
            })(someVar),
            1000
        );
        var someVar = 'goodbye';
    

This should alert 'hello' after 1 second even though someVar has by then been
overwritten.

~~~
dexen
((EDIT: was irrelevant, as pointed out by stanleydrew in the post below.
Thanks!))

~~~
stanleydrew
That's the example of what doesn't work from the beginning of section 7. That
will alert 'goodbye' after one second. I'm calling out his "fixed" code, which
is supposed to alert 'hello' after one second.

------
knuton
Please don’t vote for this article, it’s full of half-truths and
misconceptions.

You can not “fake” scope. When you call `call` on a function and pass an
object as an argument, you are calling the function as a method of that
object. This has nothing to do with a function’s scope.

~~~
raganwald
Please:

Vote for articles you feel contribute to HN, either directly or through their
discussion (a vote for a post does not necessarily imply _agreement_ , it
implies "This is worth reading.")

Please:

Point out half-truths and misconceptions.

Please don't:

Ask other people to vote for or against a post or comment.

------
olavk
The statement "Null is an Object" is probably more confusing than
enlightening. I would prefer to say that typeof(null) non-intuitively returns
the string "object".

~~~
dexen
The ECMA standard supports your story. The `null' is the only instance of type
`Null'. A Null instance does not have any properties; in particular, doesn't
have the `constructor' property all actual object do.

What alert() does is an implicit conversion to string, and _that_ is
surprisingly defined to say "object" in ECMA standard. Could be matter of
backward compatibility...

~~~
olavk
It actually makes some kind of sense in a dark, twisted way. If you think of
it in terms of the Java type system, then the type of null is arguably Object.

------
voidr
> 9\. 0.1 + 0.2 !== 0.3

You get this in most other programing languages too.

> 8\. Firefox Reads and Returns Colors in RGB, Not Hex

The title says JavaScript, this is the DOM.

> 7\. Functions Can Execute Themselves

Why is this so odd? I feel the author is too biased towards other languages.
Also his example totally misses to point of closures.

> 6\. You Can Fake Scope

No you can't fake scope, you override it. Why is this so odd? Again the author
is not looking at it correctly, this is natural if you use it correctly.

Most of this article seems to come from someone who didn't really use
JavaScript a lot, hence there is a lot of bias and prejudice. All you need to
do is tell yourself that classical OOP is not the only way to code, and you
will see that most of those things are really good stuff and not oddities.

------
olavk
My favorite oddity in JavaScript: Arrays are actually indexed by strings.
arr[17] is just syntactic sugar for arr["17"].

~~~
city41
Arrays in JavaScript are merely objects with some extra bits tacked on to make
them appear "array-like". Underneath they are still a collection of key/values
like all other JS objects.

~~~
justincormack
But the "oddity" is that unlike many languages there are only string keys.
Many languages implement the array type as a map but still distinguish between
a[17] and a["17"].

~~~
city41
Maybe I'm missing the point. I don't see how that is an oddity as all objects
in JavaScript only allow string keys.

edit: JavaScript arrays are odd in general since they are just objects
designed to look like "true" arrays. I guess I'm so used to that now that
nothing about them feels "odd" anymore.

------
al_james
This article smacks of being written by someone who came to javscript from the
design world, as opposed to coming to javascript as a programmer.

------
program
Javascript has automatic semicolon insertion. This function:

    
    
      function a() {
        return
          true;
      }
    

return _undefined_.

~~~
JeremyBanks
This Python

    
    
        def a():
            return
            False;
    

returns _None_.

~~~
qntm
That's because in Python the line break is the statement terminator.

~~~
JeremyBanks
Python and JavaScript both accept semicolons or line breaks to terminate
statements. JavaScript's syntax problems are a bit more subtle than just that.

------
buhrmi
wow this article is full of errors

