9 ms·
Zeros in JavaScript
- twerquie 13y agoSo, use triple-equals when you don't want type coercion?
- rcconf 13y agoYes, highly recommended. Just look at that chart, insanity!
- denysonique 13y agoYes, or you can use CoffeeScripts which automatically translates == into ===
- adambard 13y agoMy favorite bit is where all of these are true: '1' == 1 '1' == [1] '1' == true 1 == [1] 1 == true [1] == true But this is false: [1] == [1]
- TazeTSchnitzel 13y agoWhy would it be true? Two different instances of an object don't equal in JS. It compares identity, not value, when dealing with non-value types.
- rdtsc 13y ago> Why would it be true? It is funny that you are asking why would [1] == [1] possibly considered to be true. Let's see in a language with a sane and consistent typing system like Python: In [1]: [1]==[1] Out[1]: True Ok, let's do a crazy language from Sweden also with dynamic types but which are sane and consistent, like Erlang: 1> [1] == [1]. true Surely it will be broken in Ruby: irb(main):001:0> [1] == [1] => true Nah clearly it should be false, these crazy languages just haven't heard about objects and identities and such.
- artursapek 13y agoWhy are you being a dick? He explained the difference accurately - JS compares objects as individual objects. Arrays are objects. The other languages you cited do not work that way. Here's another example: 4 == 4 // true a = new Number(4); b = new Number(4); a == b // false a == a // true a.valueOf() // 4 b.valueOf() // 4 a.valueOf() == b.valueOf() // true And if this isn't clear yet: a = {} b = {} a == a // true a == b // false
- rdtsc 13y agoRather his tone of "Why would it be true?" sounded dick-ish. As in "How could possibly one consider [1] == [1] be true, are you crazy? It should obviously be false". So I gave a couple of examples from other dynamic languages where the the sane behavior is "obvious". I am not being a dick I am saying the language is broken. Explaining the historical context or the internal implementation of it doesn't make it unbroken. Like one can explain why COBOL uses this construct or that and how it came to be, doesn't make COBOL better or more appealing. One of course might not have a choice and be stuck using it but lying to oneself about how awesome it is, is not necessary. > The other languages you cited do not work that way. The don't, and I like how they work better. Now whether one has a choice to use or not use JS is a different topic. Usually there is no choice on the client side. But somehow extolling Javascript typing rules as being sane, making sense, or as someone below put it "brilliant" is a bit silly.
- artursapek 13y agoNo, he didn't ask it like that at all. You're putting words in his mouth instead of reading the sentence in the context of the two sentences that followed it, which made it a completely reasonable question.
- baddox 13y agoI think the point is that it's interesting that a bunch of textually-different things are considered equal, but the one textually identical pair are considered not equal.
- mikeash 13y agoBecause equality should be transitive. If a == b and b == c, then it should be the case that a == c. [1] == 1 and 1 == [1], so it should be the case that [1] == [1]. Just because it's what happens when you apply the rules of the language doesn't mean it actually makes sense.
- aegiso 13y agoA better rule is to use triple-equals always, and manually coerce if you really mean it.
- chavesn 13y agoThis is a dangerous rule; if you put this rule in the hands of a programmer who is not used to Javascript and doesn't really understand the type system, you can just as easily run into problems. This is because you require the programmer to always understand the output (and defaults) of every call made. Sometimes it's undefined. Sometimes it's null. Sometimes it's empty string. This takes experience. Example, the default for getAttribute is null, but an undefined property is undefined: document.body.getAttribute("test"); // null document.body.test; // undefined Except if it's a special property, then getAttribute might still be null, but the property empty string: var input = document.createElement("input"); input.getAttribute("value"); // null input.value; // "" Remember, "" !== null and null !== undefined.
- mistercow 13y agoThat only solves part of the problem. Coercion also happens for other operators, which ought to have at least had === equivalents. I.e. 5 + (10 * [2]) + (9 + [1/'']) // 259Infinity 5 ~+ (10 ~* [2]) ~+ (9 ~+ [1 ~/ '']) // throw exception
- lclemente 13y agoChrome: "This page is in Haitian. Would you like to translate it?" It might as well be.
- turingbook 13y agoI met with this message as well.
- cmac2992 13y agome as well. very funny
- iclelland 13y agoYou can submit the error, with the option of declaring what language the page is really in. Unfortunately, "JavaScript" isn't in the list.
- PeterisP 13y agoUgh. Many parts of javascript are nice but things like this (''==0?) make me wish for a browser-supported language that was clean.
- jonpaul 13y agoYea, or you could use "===".
- jkrems 13y agoSince comparing strings and numbers generally doesn't make a lot of sense, you could just consider it a case of "undefined behavior". As many other people will write: There's only one case I can think of where the unsafe-equals operator is reasonable and that's `a == null` to check for null/undefined.
- jonpaul 13y agoYep. Along with `== null`. I also only use "==" with `typeof` since `typeof` always returns a string.
- marcosdumay 13y agoMost languages call those situations by the name "runtime error", that is, when it is even possible that they happen at runtime. Now, I understand that javascript runs in a completely different kind of environment, and it does have the liberty of making things differently, up to a certain point. But making '' == 0 true may be a bit too far.. And making [1] == 1 true is clearly too far.
- TheZenPsycho 13y agolike what? php? visual basic? c? java? define "clean" and name one language in the history of computing that actually fits that definition.
- Dylan16807 13y agoLua.
- TallboyOne 13y agogoofy plz
- ElongatedTowel 13y agoAs a Pythonista Javascript is really strange. Let's combine two arrays with a + b. Wait, why is it now a string? Why did it just create a undefined.jpg when I run filename + '.jpg'? Ah damn, I named it filepath. I guess I check if this object is empty by comparing it to false, works for arrays right? Except it doesn't and it doesn't work for arrays either because they might contain a 0. The lesson is, always look for a method that does what you want.
- TazeTSchnitzel 13y agoThe undefined.jpg thing won't happen for variables in strict mode, it'll error. [].length is what you want for the second. IIRC [] isn't false in Python either.
- deleted 13y ago[deleted]
- gjm11 13y ago[] is false in Python; so are other empty aggregates like () and {}; collection types implemented in Python typically follow the same pattern. Thus: >>> if (): print "tuple" >>> if []: print "list" >>> if {}: print "dict" >>> if set(): print "set" >>> if "": print "string" >>> import collections >>> if collections.Counter(): print "counter" >>> if collections.deque(): print "deque" >>> (Observe that none of these prints anything.)
- TazeTSchnitzel 13y agoHuh, I recall [] not working. Interesting.
- kevin-brown 13y ago[] is false in Python, along with most empty types. http://ideone.com/ROMcag http://ideone.com/ROMcag
- mistercow 13y agoYou really wouldn't want an empty object to be equal to zero, since it might have a prototype that gives it functionality (and having the behavior conditional upon that would make it preposterously complicated to use correctly). The real mistake was making [] equal zero.
- louthy 13y agoIt's almost depressing. It must have taken significantly more work to embed these ludicrous rules when designing the language!
- TazeTSchnitzel 13y agoIt didn't. The coercing rules are fairly predictable.
- warfangle 13y agoThe coercing rules are fairly predictable, but oftentimes incomprehensible until you understand what's happening behind the scenes. It's one of the biggest weaknesses of JavaScript. Much bigger than callback hell, garbage collection cycles etc. My preferred style uses Array.prototype.join('') for string concatenation, non-coercive equality operations, and only using the + operator when doing math. It's a little cumbersome, but avoids ambiguity upon reading (and in the case of string concatenation, can be faster).
- ricardobeat 13y ago> and in the case of string concatenation, can be faster myth: http://jsperf.com/array-join-vs-string-connect/37 http://jsperf.com/array-join-vs-string-connect/37
- FreeFull 13y agoIn Firefox 25 on Linux, Array Join Nocopy seems to perform the fastest.
- warfangle 13y agoExactly. I rarely build up an array within a loop and then join it. That kind of thing just seems dirty - use a buffer! It's usually, e.g., ['some string ', someVar, ' some rest of string'].join('');
- 13y ago
- jeswin 13y agoI think this is brilliant. Most programmers prefer code to be more readable for computers than for humans. I think the problem is that we grow up with the notion that computer programs have to be very strict, in syntax, types, comparisons etc. Is there really such a need? It was for a similar reason that many people used to like XHTML over HTML. Not always because they needed to validate it, but to please the computer.
- chavesn 13y agoAs programmers we all know that Javascript has some crazy edge cases. I'm not actually all that impressed by this illustration of Javascript's equality rules. This makes it look crazy when in fact it just gives the many edge cases much stronger visual weight. The truth is, Javascript has lent strongly toward being natural in many of the most common cases -- things like being able to do `args = args || []` or simply prepending `!` to anything. Then, sometimes when you end up comparing NaN to undefined you aren't sure what the result should be or how you ended up there. Funny thing is that often when I've run into those problems myself, I pull on the thread and find it was really caused by my own poor design somewhere else.
- untog 13y agoMost programmers prefer code to be more readable for computers than for humans. They do? How can I stop them all?
- GhotiFish 13y agoyou're close, but you're not quiet there. Programmers want code to be readable to an IDE. IDE's can parse, interpret, precompile, and suggest. Languages that are very wishy washy and dynamic like javascript are absolute hell for an IDE.
- lmm 13y agoI prefer rigour for my own sanity rather than the computer's sake. In scala if I make a typo somewhere I get a compiler error that tells me the relevant line. In javascript I get "undefined has no property 'blah'", on a completely different line, at runtime.
- 13y ago
- DonPellegrino 13y ago...and that's why no one but brand new beginners use "==". If it was up to me, "use strict" would turn "===" into "==" and there would be no "===". It's too late now because it would break a lot of applications, so a new mode might be required, like "use not-completely-broken-comparisons-by-default".
- deleted 13y ago[deleted]
- ricardobeat 13y agoCoffeeScript does that.
- DonPellegrino 13y agoYup, but CoffeeScript introduces 99 other ways for beginners to create awful code, it's way easier to shoot yourself in the foot than with just JavaScript. I still prefer CoffeeScript, though.
- nkuttler 13y agoEverybody who writes JS should use something like jslint or jshint. JS has ugly parts, but most can be avoided easily.
- qwer 13y agoI honestly have no idea what's so confusing. I've been working with javascript for over a decade and have NONE of this memorized, and I never look it up or check it in the repl. It's simply not an issue if you're using jshint and unit testing your code. If you come from a static language background and you keep expecting a type-checker will save you from doing silly things like adding arrays to strings, you're always going to hate Javascript. It's a dynamically typed language, and so you have to learn the quality-control tools and practices for dynamically typed languages.
- epidemian 13y ago> It's a dynamically typed language [...] I don't think being a dynamically typed language has anything to do with having weird type coercion rules for the most basic operations. Nor with allowing seemingly invalid operations (e.g. adding arrays and strings) and returning a value instead of raising an error on those cases. > I honestly have no idea what's so confusing. Really? Comparing JS's == and + operators to other languages' (dynamically typed or not), wouldn't you say that JS's semantics are more complicated/confusing than what they should be?
- TheZenPsycho 13y agoYou're not supposed to use ==. It's there only for backwards compatibility.
- epidemian 13y agoReplace == by some other comparison operator like < or > if you prefer. The weird coercion rules still apply. >>> '5' < [6] true
- TheZenPsycho 13y agoWhy are you comparing a string to an array with a less than operator? when would that ever happen legitimately? Why would you expect any language to do something that made sense doing that?
- paragraft 13y agoReminds me of my favourite Javascript trivia question: What two values for a & b meet the following? > a === b true > Number(a) === a true > Number(b) === b true > a + b === a true > (1 / a) === (1 / b) false
- kevincennis 13y agoEdit: SPOILER ALERT 0 and -0. I never knew about this until I read a shim someone wrote for Object.is().
- TheLoneWolfling 13y agoWait, am I reading this right? [1] == [1] is false, but [1] == 1 and 1 == [1]? [0] == [0] is false, but [0] == '0' and '0' == [0]? [] == [] is false but [] == 0 and 0 == []? NaN === NaN is false? [0] + [0] = '00', but [0] * [0] = 0? Who designed this crazy language? It seems to take every quirk of every other language and combine them in the weirdest way possible. [] == [] is false, so it must be comparing pointers, right? Common gotcha of Java, etc. ...Wait, NaN === NaN is false.
- swang 13y agoNaN == NaN should return false.
- jrajav 13y agoNaN !== NaN is intended, and is the same in any other language that has NaN. It is never supposed to be equal to anything else, not even itself. As for the rest of those quirks, they mainly have to do with type coercion, the rules for which are not as difficult to learn as the whole table in the submission. The fact that type coercion is performed for == is why nobody uses ==. You also should never try + or * on arrays (and why would you?). With some simple best practices, you never end up running into most of these quirks in practice.
- kevincennis 13y agoAnother fun thing about NaN is that typeof NaN === 'number'. Which, you know... seems counterintuitive based on the fact that NaN means "Not a number".
- Dylan16807 13y agoEh. 'number' means 'IEEE 754 floating point value' and NaN is certainly one of those. Abbreviations are tricky.
- kevincennis 13y agoYeah, I understand why. I was just pointing out that on the surface, it seems kind of weird.
- kevincennis 13y agoA lot of this is sort of strange or unexpected, and that's obviously not a good thing. But 99% of the operations in that table are ones that I would never be doing in the first place. `[null] + {} == 'null[object Object]'`? Okay, fine. I might not have known that off the top of my head, but I also make it a habit not to add/concat arrays and objects. Unexpected type coercion is probably responsible for about 1% of the bugs I write. It's just not that big of a deal once you learn the common cases (`'1' == 1`, etc.)
- edgarvm 13y agowhat does mean 0[object Object]?
- Scaevolus 13y agoHere's the underlying rules of how "x == y" works: http://ecma-international.org/ecma-262/5.1/#sec-11.9.3 http://ecma-international.org/ecma-262/5.1/#sec-11.9.3 Weak typing and automatic coercions lead to some confusing results, but JS fares better than PHP.
- Segmentation 13y agoYou know you're on HN when people are defending this broken aspect of JavaScript, yet hate on the same broken aspect of PHP.
- gavinpc 13y agoI had to laugh when I saw this. It made me think of the Joshua Bloch interview in Coders at Work: > Seibel: I was reading Java Puzzlers and Effective Java and it struck me that there are a lot of little weird corners for a language that started out so simple. > Bloch: There are weird corners, yes, but that's just a fact of life; all languages have them. You haven't seen a book called C Puzzlers. Why not? > Seibel: Because it's all puzzlers. > Bloch: Yep. It would take up a shelf. In Java, the puzzlers are worth collecting precisely because you think of it as a simple language. Every language has its corner cases and Java has few enough that they're for the most part fun and interesting. Interesting, maybe. But I hope people are not using all of these. [0] [0] http://tldp.org/LDP/abs/html/exit-status.html http://tldp.org/LDP/abs/html/exit-status.html