If I execute the following snippet in FireBug console it somehow prints surprise!
:
['surprise!', 'boring'][Number(0=="")]
But why?
UPD
I am sorry, people, that was a joke! Jere is the first who noticed! Yesterday I found a ZERO WIDTH SPACE in a string, and had since then temptation to have some fun =)
If I execute the following snippet in FireBug console it somehow prints surprise!
:
['surprise!', 'boring'][Number(0=="")]
But why?
UPD
I am sorry, people, that was a joke! Jere is the first who noticed! Yesterday I found a ZERO WIDTH SPACE in a string, and had since then temptation to have some fun =)
Share Improve this question edited Jan 19, 2012 at 14:25 newtover asked Jan 19, 2012 at 14:10 newtovernewtover 32.1k11 gold badges88 silver badges89 bronze badges 6-
@micha, mind the
==
, not the===
– newtover Commented Jan 19, 2012 at 14:14 - No, his firebug recognizes mistakes and fixes them. – shift66 Commented Jan 19, 2012 at 14:14
- 2 I feel ashamed for participating... at least I guess we learned something minor – Jere Commented Jan 19, 2012 at 14:27
- @Jere, I am sorry, I do not think you were so much hurt. Now at least you know where to find during debugging – newtover Commented Jan 19, 2012 at 14:32
- True. How did you run into the zero width space in the first place? – Jere Commented Jan 19, 2012 at 14:33
5 Answers
Reset to default 10There is an extra, non visible, character between your quotes.
If you type this out, you will get 'boring' because 0=="" evaluates to true, Number(true) evalutes to 1.
Paste these two and watch the differing output:
0==""
outputs false
0==""
outputs true
The only thing I have changed is deleting the character between ""
.
0==""
is false
(Because you have a non-printing character in the string), Number(false)
is 0
(as per page 34 of the spec), and "surprise" is the 0th index of the array.
ES5 11.9.3 The ==
operator
If Type(x) is Number and Type(y) is String, return the result of the parison x == ToNumber(y).
and
The MV of StringNumericLiteral ::: [empty] is 0.
So 0==""
returns 0 == ToNumber("")
which is 0 == 0
which is true.
By the ==
conversion rules 0==""
is true
ES5 15.7.1.1 Number ( value ) invokes ES5 9.3 toNumber toNumber(true) === 1
And ["suprize!", "boring"][1]
returns "boring"
which is clearly incorrect.
Why is it correct? Because
"".charCodeAt(0) === 8203
Your string literal is not the empty string. You have a zero width space in your string.
Now if we go back to ES5 11.9.3 ==
operator we see
If the grammar cannot interpret the String as an expansion of StringNumericLiteral
Which means
0==""
0==NaN
false
toNumber(false) === 0
Number(0=="") === 0
["suprize!", "boring"][0] === "suprize!"
['surprise!', 'boring'][Number(0=="")]
will return 'boring' becouse your code:
Number(0=="") //returns true
But your code is diferent, you have an invisible char in your text, that's why is returning false.
If you write the code correctly will return true and the result will be boring
as expected.
But if copy and paste your code, will return false, that's why you have a char between the "" (you can check using keyboard or "".length)
so your code will return false, that will be 0 then return 'surprise!'
You are cheating man :P
['surprise!', 'boring'][Number(0=="")]
"".length //returns 1 ;)
"" != "" // OH GOD THIS IS TRUE :P
I get boring when ran this in console console.log(['surpeise!','boring'][Number(0=="")])