10 ms·
Oddities about JavaScript
- olavk 15y agoThe 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 15y agoThe 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 15y agoIt 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.
- knuton 15y agoPlease 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 15y agoPlease: 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.
- unwind 15y agoThat 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 http://en.wikipedia.org/wiki/NaN).
- dexen 15y agoNothing 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_all_other_numbers http://en.wikipedia.org/wiki/Invalid_proof#All_numbers_equal...
- jerf 15y agoThe 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 http://en.wikipedia.org/wiki/Binary_relation
- dexen 15y ago> (...)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? :-)
- olavk 15y agoMy favorite oddity in JavaScript: Arrays are actually indexed by strings. arr[17] is just syntactic sugar for arr["17"].
- city41 15y agoArrays 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 15y agoBut 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 15y agoMaybe 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.
- program 15y agoJavascript has automatic semicolon insertion. This function: function a() { return true; } return undefined.
- JeremyBanks 15y agoThis Python def a(): return False; returns None.
- qntm 15y agoThat's because in Python the line break is the statement terminator.
- JeremyBanks 15y agoPython and JavaScript both accept semicolons or line breaks to terminate statements. JavaScript's syntax problems are a bit more subtle than just that.
- riffraff 15y agoSame in ruby def foo return true end returns "nil"
- knowtheory 15y agoI don't like referring to this as "automatic semicolon insertion". The behavior you're referring to here is really about line termination/continuation. var a = 42 is only parseable one way because assignment requires an argument. Javascript just happens to make assumptions with certain kinds of ambiguities, but then, all programming languages do.
- program 15y agoActually that is the name that appears in the ECMAScript official language specification: http://bclary.com/2004/11/07/#a-7.9.1 http://bclary.com/2004/11/07/#a-7.9.1
- buhrmi 15y agowow this article is full of errors
- stanleydrew 15y agoSection 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 15y ago((EDIT: was irrelevant, as pointed out by stanleydrew in the post below. Thanks!))
- stanleydrew 15y agoThat'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.
- Mitya 15y ago@stanleydrew - I changed this code late last night after I realised my mistake here. Of course I had meant to return a function from the SEF, which the code in the article now does. Apologies for the oversight.
- al_james 15y agoThis article smacks of being written by someone who came to javscript from the design world, as opposed to coming to javascript as a programmer.
- voidr 15y ago> 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.