how to understand javascript coercion? [closed] - javascript

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 6 years ago.
Improve this question
I was watching this talk, and on 16:34 there is a javascript coercion test:
5 - "4" // 1
5 + "4" // 54
+!{}[true] // 1
+[1] // 1
+[1, 2] // NaN
7 - "a" // NaN
7 / 0 // Infinity
What is the exact logic behind those calculations?

5 - "4" // 1
The - operator coerces its operands to numbers. See the subtraction operator and the abstract ToNumber operation it uses.
5 + "4" // 54
When either operand is a string, the + is string concatenation, not addition, and the other operand is coerced to string if necessary. See the addition operator and the abstract ToPrimitive and ToString operations.
+!{}[true] // 1
Explaining this is pointless. Don't do that in your code.
Oh, okay:
{}[true] is evaluated first. The true is coerced to "true" (via ToString linked above) because it's used in a property accessor and isn't a Symbol. {} is an empty object, so {}[true] is undefined, leaving us with +!undefined.
!undefined is true, because it coerces undefined to a boolean via the abstract ToBoolean operation, and then negates that to get true.
+true is 1, because of ToNumber linked above.
+[1] // 1
[1] is an array with a 1 in it. Applying + to it runs it through ToPrimitive, which ultimate ends up being [1].join(","), giving us..."1". +"1" is 1 thanks to ToNumber.
+[1, 2] // NaN
Almost exactly like the above, but since the string "1,2" can't be completely parsed as a number, we get NaN.
7 - "a" // NaN
Almost exactly like our first example. ToNumber("a") is NaN, and any calculation involving NaN (such as substraction) results in NaN.
7 / 0 // Infinity
In JavaScript, division by 0 is defined as Infinity; see the Applying the / Operator.
As you can see, these are all understandable, with effort, by referring to the specification. Some are tricky, but really the tricky ones are things you'd almost never run into in the real world.

What is your resource of choice to understand type coercion in javascript?
The spec.
Some examples:
to understand why 5 - "4" === 1, I would look for the binary - operator in the spec and see that ToNumber is called on each argument.
to understand why +!{}[true] === 1, I would first understand that {}[true] uses the bracket notation property accessor, which uses ToPropertyKey on the value, which will use ToString on true since true is not a Symbol, so it is the same as {}["true"], and since that object has no property called "true" the result is undefined, then to understand why +!undefined === 1 I would look at the spec for the unary logical ! operator and see that it uses ToBoolean (before negating the result), and ToBoolean converts undefined to false. To understand why +true === 1, I would look at the spec for the unary + operator and see that it calls ToNumber on its operand, and ToNumber evaluates true to 1.
The rules are actually pretty straightforward and intuitive once you are accustomed to them, which happens pretty quickly. If you learn them from the spec, there are no surprises.

To understand coercion you simply need to understand what is going on. Firstly, JavaScript is a dynamically typed language. Unlike some other programming languages, JavaScript doesn't require you to define a variable's type.
Example:
var a = 1
//you are not telling JavaScript that
// 1 is an integer, you are just defining it as is
So prior to attempting to breakdown the examples you have listed, you must next understand that to apply a method to an object, both methods have to be the same type.
Example:
5 + "hello" = ?
// in math, you can't possibly add a number to a word right?
// and JavaScript realises that.
// But instead of throwing an error, it "coerces" the
// integer 5, into a string "5",
// giving you the answer "5hello"
Lastly I would use the first 2 examples as a contrast for coercion.
The first one states 5 - "4" = 1 while the second one is 5 + "4" = "54".
The main reason for difference in result is largely because of the symbol involved. While we can "add" strings together (simply joining them) but how exactly should we be "minusing" strings?
While this may be a very brief explanation of coercion in JavaScript but hopefully it gives you a clearer picture.

to understand the logic between symbold that have functions:
1.) 5 (integer type) minus 4 (string type) results 1, 4 implemented as int
2.) 5 (integer type) plus 4 (string type) results 54, 5 implemented as string
3.)+plus !is not {} brackets results true
4.)plus array one+[1], results 1
5.)plus array one and two(multiple data set), results Nan, not do-able
6.)7 (int) minus string("a"), results Nan since its not possible
7.)7 divide by 0 , results in infinity like in math functions if a number is divided by 0 is always infinite
Wiki:Coercion /koʊˈɜːrʃən/ is the practice of forcing another party to act in an involuntary manner by use of intimidation or threats or some other form of pressure or force.
like number 1 is int against string which does not fit and forcefully written
It's just to help you understand the logic behind the language.Hope this helps :)

Related

Why does Number('') returns 0 whereas parseInt('') returns NaN

I have gone through similar questions and answers on StackOverflow and found this:
parseInt("123hui")
returns 123
Number("123hui")
returns NaN
As, parseInt() parses up to the first non-digit and returns whatever it had parsed and Number() tries to convert the entire string into a number, why unlikely behaviour in case of parseInt('') and Number('').
I feel ideally parseInt should return NaNjust like it does with Number("123hui")
Now my next question:
As 0 == '' returns true I believe it interprets like 0 == Number('') which is true. So does the compiler really treat it like 0 == Number('') and not like 0 == parseInt('') or am I missing some points?
The difference is due in part to Number() making use of additional logic for type coercion. Included in the rules it follows for that is:
A StringNumericLiteral that is empty or contains only white space is converted to +0.
Whereas parseInt() is defined to simply find and evaluate numeric characters in the input, based on the given or detected radix. And, it was defined to expect at least one valid character.
13) If S contains a code unit that is not a radix-R digit, let Z be the substring of S consisting of all code units before the first such code unit; otherwise, let Z be S.
14) If Z is empty, return NaN.
Note: 'S' is the input string after any leading whitespace is removed.
As 0=='' returns true I believe it interprets like 0==Number('') [...]
The rules that == uses are defined as Abstract Equality.
And, you're right about the coercion/conversion that's used. The relevant step is #6:
If Type(x) is Number and Type(y) is String,
return the result of the comparison x == ToNumber(y).
To answer your question about 0==''returning true :
Below is the comparison of a number and string:
The Equals Operator (==)
Type (x) Type(y) Result
-------------------------------------------
x and y are the same type Strict Equality (===) Algorithm
Number String x == toNumber(y)
and toNumber does the following to a string argument:
toNumber:
Argument type Result
------------------------
String In effect evaluates Number(string)
“abc” -> NaN
“123” -> 123
Number('') returns 0. So that leaves you with 0==0 which is evaluated using Strict Equality (===) Algorithm
The Strict Equals Operator (===)
Type values Result
----------------------------------------------------------
Number x same value as y true
(but not NaN)
You can find the complete list # javascriptweblog.wordpress.com - truth-equality-and-javascript.
parseInt("") is NaN because the standard says so even if +"" is 0 instead (also simply because the standard says so, implying for example that "" == 0).
Don't look for logic in this because there's no deep profound logic, just history.
You are in my opinion making a BIG mistake... the sooner you correct it the better will be for your programming life with Javascript. The mistake is that you are assuming that every choice made in programming languages and every technical detail about them is logical. This is simply not true.
Especially for Javascript.
Please remeber that Javascript was "designed" in a rush and, just because of fate, it became extremely popular overnight. This forced the community to standardize it before any serious thought to the details and therefore it was basically "frozen" in its current sad state before any serious testing on the field.
There are parts that are so bad they aren't even funny (e.g. with statement or the == equality operator that is so broken that serious js IDEs warn about any use of it: you get things like A==B, B==C and A!=C even using just normal values and without any "special" value like null, undefined, NaN or empty strings "" and not because of precision problems).
Nonsense special cases are everywhere in Javascript and trying to put them in a logical frame is, unfortunately, a wasted effort. Just learn its oddities by reading a lot and enjoy the fantastic runtime environment it provides (this is where Javascript really shines... browsers and their JIT are a truly impressive piece of technology: you can write a few lines and get real useful software running on a gajillion of different computing devices).
The official standard where all oddities are enumerated is quite hard to read because aims to be very accurate, and unfortunately the rules it has to specify are really complex.
Moreover as the language gains more features the rules will get even more and more complex: for example what is for ES5 just another weird "special" case (e.g. ToPrimitive operation behavior for Date objects) becomes a "normal" case in ES6 (where ToPrimitive can be customized).
Not sure if this "normalization" is something to be happy about... the real problem is the frozen starting point and there are no easy solutions now (if you don't want to throw away all existing javascript code, that is).
The normal path for a language is starting clean and nice and symmetric and small. Then when facing real world problems the language gains (is infected by) some ugly parts (because the world is ugly and asymmetrical).
Javascript is like that. Except that it didn't start nice and clean and moreover there was no time to polish it before throwing it in the game.

How does “+var === +var” type is number even if we use it in number string [duplicate]

Just out of curiosity.
It doesn't seem very logical that typeof NaN is number. Just like NaN === NaN or NaN == NaN returning false, by the way. Is this one of the peculiarities of JavaScript, or would there be a reason for this?
Edit: thanks for your answers. It's not an easy thing to get ones head around though. Reading answers and the wiki I understood more, but still, a sentence like
A comparison with a NaN always returns an unordered result even when comparing with itself. The comparison predicates are either signaling or non-signaling, the signaling versions signal an invalid exception for such comparisons. The equality and inequality predicates are non-signaling so x = x returning false can be used to test if x is a quiet NaN.
just keeps my head spinning. If someone can translate this in human (as opposed to, say, mathematician) readable language, I would be grateful.
Well, it may seem a little strange that something called "not a number" is considered a number, but NaN is still a numeric type, despite that fact :-)
NaN just means the specific value cannot be represented within the limitations of the numeric type (although that could be said for all numbers that have to be rounded to fit, but NaN is a special case).
A specific NaN is not considered equal to another NaN because they may be different values. However, NaN is still a number type, just like 2718 or 31415.
As to your updated question to explain in layman's terms:
A comparison with a NaN always returns an unordered result even when comparing with itself. The comparison predicates are either signalling or non-signalling, the signalling versions signal an invalid exception for such comparisons. The equality and inequality predicates are non-signalling so x = x returning false can be used to test if x is a quiet NaN.
All this means is (broken down into parts):
A comparison with a NaN always returns an unordered result even when comparing with itself.
Basically, a NaN is not equal to any other number, including another NaN, and even including itself.
The comparison predicates are either signalling or non-signalling, the signalling versions signal an invalid exception for such comparisons.
Attempting to do comparison (less than, greater than, and so on) operations between a NaN and another number can either result in an exception being thrown (signalling) or just getting false as the result (non-signalling or quiet).
The equality and inequality predicates are non-signalling so x = x returning false can be used to test if x is a quiet NaN.
Tests for equality (equal to, not equal to) are never signalling so using them will not cause an exception. If you have a regular number x, then x == x will always be true. If x is a NaN, then x == x will always be false. It's giving you a way to detect NaN easily (quietly).
It means Not a Number. It is not a peculiarity of javascript but common computer science principle.
From http://en.wikipedia.org/wiki/NaN:
There are three kinds of operation
which return NaN:
Operations with a NaN as at least one operand
Indeterminate forms
The divisions 0/0, ∞/∞, ∞/−∞, −∞/∞, and −∞/−∞
The multiplications 0×∞ and 0×−∞
The power 1^∞
The additions ∞ + (−∞), (−∞) + ∞ and equivalent subtractions.
Real operations with complex results:
The square root of a negative number
The logarithm of a negative number
The tangent of an odd multiple of 90 degrees (or π/2 radians)
The inverse sine or cosine of a number which is less than −1 or
greater than +1.
All these values may not be the same. A simple test for a NaN is to test value == value is false.
The ECMAScript (JavaScript) standard specifies that Numbers are IEEE 754 floats, which include NaN as a possible value.
ECMA 262 5e Section 4.3.19: Number value
primitive value corresponding to a double-precision 64-bit binary format IEEE 754 value.
ECMA 262 5e Section 4.3.23: NaN
Number value that is a IEEE 754 "Not-a-Number" value.
IEEE 754 on Wikipedia
The IEEE Standard for Floating-Point Arithmetic is a technical standard established by the Institute of Electrical and Electronics Engineers and the most widely used standard for floating-point computation [...]
The standard defines
arithmetic formats: sets of binary and decimal floating-point data, which consist of finite numbers (including signed zeros and subnormal numbers), infinities, and special "not a number" values (NaNs)
[...]
typeof NaN returns 'number' because:
ECMAScript spec says the Number type includes NaN:
4.3.20 Number type
set of all possible Number values including the special “Not-a-Number”
(NaN) values, positive infinity, and negative infinity
So typeof returns accordingly:
11.4.3 The typeof Operator
The production UnaryExpression : typeof UnaryExpression is
evaluated as follows:
Let val be the result of evaluating UnaryExpression.
If Type(val) is Reference, then
If IsUnresolvableReference(val) is true, return "undefined".
Let val be GetValue(val).
Return a String determined by Type(val) according to Table 20.
​
Table 20 — typeof Operator Results
==================================================================
| Type of val | Result |
==================================================================
| Undefined | "undefined" |
|----------------------------------------------------------------|
| Null | "object" |
|----------------------------------------------------------------|
| Boolean | "boolean" |
|----------------------------------------------------------------|
| Number | "number" |
|----------------------------------------------------------------|
| String | "string" |
|----------------------------------------------------------------|
| Object (native and does | "object" |
| not implement [[Call]]) | |
|----------------------------------------------------------------|
| Object (native or host and | "function" |
| does implement [[Call]]) | |
|----------------------------------------------------------------|
| Object (host and does not | Implementation-defined except may |
| implement [[Call]]) | not be "undefined", "boolean", |
| | "number", or "string". |
------------------------------------------------------------------
This behavior is in accordance with IEEE Standard for Floating-Point Arithmetic (IEEE 754):
4.3.19 Number value
primitive value corresponding to a double-precision 64-bit binary
format IEEE 754 value
4.3.23 NaN
number value that is a IEEE 754 “Not-a-Number” value
8.5 The Number Type
The Number type has exactly 18437736874454810627 (that is, 253−264+3)
values, representing the double-precision 64-bit format IEEE 754
values as specified in the IEEE Standard for Binary Floating-Point
Arithmetic, except that the 9007199254740990 (that is, 253−2) distinct
“Not-a-Number” values of the IEEE Standard are represented in
ECMAScript as a single special NaN value. (Note that the NaN value
is produced by the program expression NaN.)
NaN != NaN because they are not necessary the SAME non-number. Thus it makes a lot of sense...
Also why floats have both +0.00 and -0.00 that are not the same. Rounding may do that they are actually not zero.
As for typeof, that depends on the language. And most languages will say that NaN is a float, double or number depending on how they classify it... I know of no languages that will say this is an unknown type or null.
NaN is a valid floating point value (http://en.wikipedia.org/wiki/NaN)
and NaN === NaN is false because they're not necessarily the same non-number
NaN stands for Not a Number. It is a value of numeric data types (usually floating point types, but not always) that represents the result of an invalid operation such as dividing by zero.
Although its names says that it's not a number, the data type used to hold it is a numeric type. So in JavaScript, asking for the datatype of NaN will return number (as alert(typeof(NaN)) clearly demonstrates).
A better name for NaN, describing its meaning more precisely and less confusingly, would be a numerical exception. It is really another kind of exception object disguised as having primitive type (by the language design), where at the same it is not treated as primitive in its false self-comparison. Whence the confusion. And as long as the language "will not make its mind" to choose between proper exception object and primitive numeral, the confusion will stay.
The infamous non-equality of NaN to itself, both == and === is a manifestation of the confusing design forcing this exception object into being a primitive type. This breaks the fundamental principle that a primitive is uniquely determined by its value. If NaN is preferred to be seen as exception (of which there can be different kinds), then it should not be "sold" as primitive. And if it is wanted to be primitive, that principle must hold. As long as it is broken, as we have in JavaScript, and we can't really decide between the two, the confusion leading to unnecessary cognitive load for everyone involved will remain. Which, however, is really easy to fix by simply making the choice between the two:
either make NaN a special exception object containing the useful information about how the exception arose, as opposed to throwing that information away as what is currently implemented, leading to harder-to-debug code;
or make NaN an entity of the primitive type number (that could be less confusingly called "numeric"), in which case it should be equal to itself and cannot contain any other information; the latter is clearly an inferior choice.
The only conceivable advantage of forcing NaN into number type is being able to throw it back into any numerical expression. Which, however, makes it brittle choice, because the result of any numerical expression containing NaN will either be NaN, or leading to unpredictable results such as NaN < 0 evaluating to false, i.e. returning boolean instead of keeping the exception.
And even if "things are the way they are", nothing prevents us from making that clear distinction for ourselves, to help make our code more predictable and easierly debuggable. In practice, that means identifying those exceptions and dealing with them as exceptions. Which, unfortunately, means more code but hopefully will be mitigated by tools such as TypeScript of Flowtype.
And then we have the messy quiet vs noisy aka signalling NaN distinction. Which really is about how exceptions are handled, not the exceptions themselves, and nothing different from other exceptions.
Similarly, Infinity and +Infinity are elements of numeric type arising in the extension of the real line but they are not real numbers. Mathematically, they can be represented by sequences of real numbers converging to either + or -Infinity.
Javascript uses NaN to represent anything it encounters that can't be represented any other way by its specifications. It does not mean it is not a number. It's just the easiest way to describe the encounter. NaN means that it or an object that refers to it could not be represented in any other way by javascript. For all practical purposes, it is 'unknown'. Being 'unknown' it cannot tell you what it is nor even if it is itself. It is not even the object it is assigned to. It can only tell you what it is not, and not-ness or nothingness can only be described mathematically in a programming language. Since mathematics is about numbers, javascript represents nothingness as NaN. That doesn't mean it's not a number. It means we can't read it any other way that makes sense. That's why it can't even equal itself. Because it doesn't.
This is simply because NaN is a property of the Number object in JS, It has nothing to do with it being a number.
The best way to think of NAN is that its not a known number. Thats why NAN != NAN because each NAN value represents some unique unknown number. NANs are necessary because floating point numbers have a limited range of values. In some cases rounding occurs where the lower bits are lost which leads to what appears to be nonsense like 1.0/11*11 != 1.0. Really large values which are greater are NANs with infinity being a perfect example.
Given we only have ten fingers any attempt to show values greater than 10 are impossible, which means such values must be NANs because we have lost the true value of this greater than 10 value. The same is true of floating point values, where the value exceeds the limits of what can be held in a float.
NaN is still a numeric type, but it represents value that could not represent a valid number.
Because NaN is a numeric data type.
NaN is a number from a type point of view, but is not a normal number like 1, 2 or 329131. The name "Not A Number" refers to the fact that the value represented is special and is about the IEEE format spec domain, not javascript language domain.
If using jQuery, I prefer isNumeric over checking the type:
console.log($.isNumeric(NaN)); // returns false
console.log($.type(NaN)); // returns number
http://api.jquery.com/jQuery.isNumeric/
Javascript has only one numeric data type, which is the standard 64-bit double-precision float. Everything is a double. NaN is a special value of double, but it's a double nonetheless.
All that parseInt does is to "cast" your string into a numeric data type, so the result is always "number"; only if the original string wasn't parseable, its value will be NaN.
We could argue that NaN is a special case object. In this case, NaN's object represents a number that makes no mathematical sense. There are some other special case objects in math like INFINITE and so on.
You can still do some calculations with it, but that will yield strange behaviours.
More info here: http://www.concentric.net/~ttwang/tech/javafloat.htm (java based, not javascript)
You've got to love Javascript. It has some interesting little quirks.
http://wtfjs.com/page/13
Most of those quirks can be explained if you stop to work them out logically, or if you know a bit about number theory, but nevertheless they can still catch you out if you don't know about them.
By the way, I recommend reading the rest of http://wtfjs.com/ -- there's a lot more interesting quirks than this one to be found!
The value NaN is really the Number.NaN hence when you ask if it is a number it will say yes. You did the correct thing by using the isNaN() call.
For information, NaN can also be returned by operations on Numbers that are not defined like divisions by zero or square root of a negative number.
It is special value of Number type as POSITIVE_INFINITY
Why? By design
An example
Imagine We are converting a string to a number:
Number("string"); // returns NaN
We changed the data type to number but its value is not a number!

Why does typeof 3>2 return false in javascript console? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
The following link provides a description and examples about how typeof works:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof
Because typeof 3 is not more than 2.
You need parentheses.
To explain what's going on, the interpreter treats it as:
(typeof 3) > 2
The typeof operator always returns a string, and 3 is a number so the expression resolves to:
'number' > 2
The Greater-than Operator ( > ) applies the Abstract Relational Comparison Algorithm to get the result of the comparison. Since 'number' is a String, it's converted to a Number using the internal ToNumber operation (step 3a). A string that doesn't contain a number literal (e.g. "3") results in NaN (see note below), so now the expression is:
NaN > 2
Step 3c says if the left hand expression is NaN, return undefined (that is, the special undefined value, not the string 'undefined').
So undefined is returned, and step 6 of the greater–than operator algorithm says:
If [the result] is undefined, return false. Otherwise, return [the result].
so ultimately, the expression returns false.
Note: a string containing only whitespace (one or more spaces, tabs, newlines, etc.) converts to the number 0, which is the only case where a string that isn't a numeric literal converts to a number value other than NaN. See ToNumber Applied to the String Type.
In JavaScript the operator "typeof" has a precedence of 4 while the operator greater ">" than has a precedence of 8, so according to the example mentioned in the question typeof 3 gets evaluated first and then compared to 2 which returns false.
More details can be found about precedence and associativity of operators at: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence

Why and how does ([![]]+[][[]])[+!+[]+[+[]]] evaluate to the letter "i"? [duplicate]

This question already has answers here:
Why does ++[[]][+[]]+[+[]] return the string "10"?
(10 answers)
(![]+[])[+[]]... Explain why this works
(1 answer)
Closed 9 years ago.
While reading this article posted on dzone I found a snippet of JavaScript originally posted on Twitter by Marcus Lagergren.
The following code apparently prints the string "fail"
(![]+[])[+[]]+(![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]];
This involves implicit type casting and I'm trying to understand how exactly this line is interpreted.
I've isolated each character
(![]+[])[+[]] prints "f"
(![]+[])[+!+[]] prints "a"
([![]]+[][[]])[+!+[]+[+[]]] prints "i"
(![]+[])[!+[]+!+[]] prints "l"
I've also managed to break down the expressions returning each letter apart from "i"
letter "f"
![] an empty array is an Object, which according to ECMAScript documentation, point 9.2 evaluates to true when converted to a boolean so this is false
false+[] as per Point 11.6.1 both arguments of the binary + operator get converted to String, therefore we get "false"+"", which evaluates "false"
+[] a unary plus operator causes a ToNumber conversion followed by a ToPrimitive conversion if the argument is an Object. The result of such conversion is determined by calling the [[DefaultValue]] internal method of the object. In case of an empty array, it defaults to 0.
(ECMAScript Documentation, sections: 11.4.6, 9.3, 9.1 )
"false"[0] we're accessing the character at index 0, hence the "f"
letter "a"
Same story, the only difference here are additional conversions in the part in square brackets (which evaluates to a number to point at another character in the string "false"), triggered by the use of unary + and ! operators.
+[] evaluates to 0, as explained above.
!0 evaluates to true as defined in Section 9.2 and Section 11.4.9. First, 0 is converted to a boolean false and then the operator inverts the value.
+true again, the unary plus triggers a ToNumber conversion, which returns a 1 for binary true
(Section 11.4.6 and 9.3)
"false"[1] returns the second character in the string, which is "a"
letter "l"
!+[] evaluates to true as explained above
true+true using the binary + on primitives triggers a ToNumber conversion. In case of true, its result is 1 and 1+1 equals 2
"false"[2] - self explanatory
letter "i"
What leaves me stumped is the letter "i". I can see that the second part (in square brackets) evaluates to the string "10" and that the first part (in parentheses) returns "falseundefined" but I can't make heads or tails of how this is happening. Could someone explain it step by step? Especially the magic that happens with square brackets? (arrays and array access)
If possible, I'd like each step to contain a link to the underlying ECMAScript rules.
What I find the most cryptic is this part: [][[]]
Your cryptic part isn't all that cryptic if you rewrite it a little:
[]['']
[] will be coerced into a string because it isn't an integer, so you're looking for a property of [] with the name '' (an empty string). You'll just get undefined, as there is no property with that name.
As for the actual letter, break the expression up into the two main components:
The string ([![]]+[][[]]):
[![]] is [false].
[][[]] is undefined.
Add them together and you get "falseundefined".
And the index: [+!+[]+[+[]]]. Some whitespace and parentheses will make the operations much clearer: [+(!(+[])) + [+[]]]:
[+[]] is [0].
+[] coerces [] to an integer, so you get 0.
!+[] coerces 0 to a boolean and negates it, so you get true.
+!+[] coerces true to an integer, so you get 1.
Add them together, and you get ["10"].
When using a string to access the properties of the array and the string happens to be an element of the array, the string is coerced into an integer and you get back the actual element of the array:
> [1, 2, 3]["0"]
1
> [1, 2, 3]["1"]
2
So your final result is:
> "falseundefined"["10"]
"i"
Read this answer for an explanation of the [false] + undefined part.
([![]]+[][[]])[+!+[]+[+[]]] has two parts :
([![]]+[][[]]) and the other which you found yourself.
![] returns false. Then we use [...] to get the .toString() behavior of +.
([]+[] is the same as [].toString()+[].toString())
the [][[]] is undefined because we're trying to access the index [] (or [].toString(), which is '') of [] which is undefined.
Sorry for the previous answered, I misread your comment totally.

Why does typeof NaN return 'number'?

Just out of curiosity.
It doesn't seem very logical that typeof NaN is number. Just like NaN === NaN or NaN == NaN returning false, by the way. Is this one of the peculiarities of JavaScript, or would there be a reason for this?
Edit: thanks for your answers. It's not an easy thing to get ones head around though. Reading answers and the wiki I understood more, but still, a sentence like
A comparison with a NaN always returns an unordered result even when comparing with itself. The comparison predicates are either signaling or non-signaling, the signaling versions signal an invalid exception for such comparisons. The equality and inequality predicates are non-signaling so x = x returning false can be used to test if x is a quiet NaN.
just keeps my head spinning. If someone can translate this in human (as opposed to, say, mathematician) readable language, I would be grateful.
Well, it may seem a little strange that something called "not a number" is considered a number, but NaN is still a numeric type, despite that fact :-)
NaN just means the specific value cannot be represented within the limitations of the numeric type (although that could be said for all numbers that have to be rounded to fit, but NaN is a special case).
A specific NaN is not considered equal to another NaN because they may be different values. However, NaN is still a number type, just like 2718 or 31415.
As to your updated question to explain in layman's terms:
A comparison with a NaN always returns an unordered result even when comparing with itself. The comparison predicates are either signalling or non-signalling, the signalling versions signal an invalid exception for such comparisons. The equality and inequality predicates are non-signalling so x = x returning false can be used to test if x is a quiet NaN.
All this means is (broken down into parts):
A comparison with a NaN always returns an unordered result even when comparing with itself.
Basically, a NaN is not equal to any other number, including another NaN, and even including itself.
The comparison predicates are either signalling or non-signalling, the signalling versions signal an invalid exception for such comparisons.
Attempting to do comparison (less than, greater than, and so on) operations between a NaN and another number can either result in an exception being thrown (signalling) or just getting false as the result (non-signalling or quiet).
The equality and inequality predicates are non-signalling so x = x returning false can be used to test if x is a quiet NaN.
Tests for equality (equal to, not equal to) are never signalling so using them will not cause an exception. If you have a regular number x, then x == x will always be true. If x is a NaN, then x == x will always be false. It's giving you a way to detect NaN easily (quietly).
It means Not a Number. It is not a peculiarity of javascript but common computer science principle.
From http://en.wikipedia.org/wiki/NaN:
There are three kinds of operation
which return NaN:
Operations with a NaN as at least one operand
Indeterminate forms
The divisions 0/0, ∞/∞, ∞/−∞, −∞/∞, and −∞/−∞
The multiplications 0×∞ and 0×−∞
The power 1^∞
The additions ∞ + (−∞), (−∞) + ∞ and equivalent subtractions.
Real operations with complex results:
The square root of a negative number
The logarithm of a negative number
The tangent of an odd multiple of 90 degrees (or π/2 radians)
The inverse sine or cosine of a number which is less than −1 or
greater than +1.
All these values may not be the same. A simple test for a NaN is to test value == value is false.
The ECMAScript (JavaScript) standard specifies that Numbers are IEEE 754 floats, which include NaN as a possible value.
ECMA 262 5e Section 4.3.19: Number value
primitive value corresponding to a double-precision 64-bit binary format IEEE 754 value.
ECMA 262 5e Section 4.3.23: NaN
Number value that is a IEEE 754 "Not-a-Number" value.
IEEE 754 on Wikipedia
The IEEE Standard for Floating-Point Arithmetic is a technical standard established by the Institute of Electrical and Electronics Engineers and the most widely used standard for floating-point computation [...]
The standard defines
arithmetic formats: sets of binary and decimal floating-point data, which consist of finite numbers (including signed zeros and subnormal numbers), infinities, and special "not a number" values (NaNs)
[...]
typeof NaN returns 'number' because:
ECMAScript spec says the Number type includes NaN:
4.3.20 Number type
set of all possible Number values including the special “Not-a-Number”
(NaN) values, positive infinity, and negative infinity
So typeof returns accordingly:
11.4.3 The typeof Operator
The production UnaryExpression : typeof UnaryExpression is
evaluated as follows:
Let val be the result of evaluating UnaryExpression.
If Type(val) is Reference, then
If IsUnresolvableReference(val) is true, return "undefined".
Let val be GetValue(val).
Return a String determined by Type(val) according to Table 20.
​
Table 20 — typeof Operator Results
==================================================================
| Type of val | Result |
==================================================================
| Undefined | "undefined" |
|----------------------------------------------------------------|
| Null | "object" |
|----------------------------------------------------------------|
| Boolean | "boolean" |
|----------------------------------------------------------------|
| Number | "number" |
|----------------------------------------------------------------|
| String | "string" |
|----------------------------------------------------------------|
| Object (native and does | "object" |
| not implement [[Call]]) | |
|----------------------------------------------------------------|
| Object (native or host and | "function" |
| does implement [[Call]]) | |
|----------------------------------------------------------------|
| Object (host and does not | Implementation-defined except may |
| implement [[Call]]) | not be "undefined", "boolean", |
| | "number", or "string". |
------------------------------------------------------------------
This behavior is in accordance with IEEE Standard for Floating-Point Arithmetic (IEEE 754):
4.3.19 Number value
primitive value corresponding to a double-precision 64-bit binary
format IEEE 754 value
4.3.23 NaN
number value that is a IEEE 754 “Not-a-Number” value
8.5 The Number Type
The Number type has exactly 18437736874454810627 (that is, 253−264+3)
values, representing the double-precision 64-bit format IEEE 754
values as specified in the IEEE Standard for Binary Floating-Point
Arithmetic, except that the 9007199254740990 (that is, 253−2) distinct
“Not-a-Number” values of the IEEE Standard are represented in
ECMAScript as a single special NaN value. (Note that the NaN value
is produced by the program expression NaN.)
NaN != NaN because they are not necessary the SAME non-number. Thus it makes a lot of sense...
Also why floats have both +0.00 and -0.00 that are not the same. Rounding may do that they are actually not zero.
As for typeof, that depends on the language. And most languages will say that NaN is a float, double or number depending on how they classify it... I know of no languages that will say this is an unknown type or null.
NaN is a valid floating point value (http://en.wikipedia.org/wiki/NaN)
and NaN === NaN is false because they're not necessarily the same non-number
NaN stands for Not a Number. It is a value of numeric data types (usually floating point types, but not always) that represents the result of an invalid operation such as dividing by zero.
Although its names says that it's not a number, the data type used to hold it is a numeric type. So in JavaScript, asking for the datatype of NaN will return number (as alert(typeof(NaN)) clearly demonstrates).
A better name for NaN, describing its meaning more precisely and less confusingly, would be a numerical exception. It is really another kind of exception object disguised as having primitive type (by the language design), where at the same it is not treated as primitive in its false self-comparison. Whence the confusion. And as long as the language "will not make its mind" to choose between proper exception object and primitive numeral, the confusion will stay.
The infamous non-equality of NaN to itself, both == and === is a manifestation of the confusing design forcing this exception object into being a primitive type. This breaks the fundamental principle that a primitive is uniquely determined by its value. If NaN is preferred to be seen as exception (of which there can be different kinds), then it should not be "sold" as primitive. And if it is wanted to be primitive, that principle must hold. As long as it is broken, as we have in JavaScript, and we can't really decide between the two, the confusion leading to unnecessary cognitive load for everyone involved will remain. Which, however, is really easy to fix by simply making the choice between the two:
either make NaN a special exception object containing the useful information about how the exception arose, as opposed to throwing that information away as what is currently implemented, leading to harder-to-debug code;
or make NaN an entity of the primitive type number (that could be less confusingly called "numeric"), in which case it should be equal to itself and cannot contain any other information; the latter is clearly an inferior choice.
The only conceivable advantage of forcing NaN into number type is being able to throw it back into any numerical expression. Which, however, makes it brittle choice, because the result of any numerical expression containing NaN will either be NaN, or leading to unpredictable results such as NaN < 0 evaluating to false, i.e. returning boolean instead of keeping the exception.
And even if "things are the way they are", nothing prevents us from making that clear distinction for ourselves, to help make our code more predictable and easierly debuggable. In practice, that means identifying those exceptions and dealing with them as exceptions. Which, unfortunately, means more code but hopefully will be mitigated by tools such as TypeScript of Flowtype.
And then we have the messy quiet vs noisy aka signalling NaN distinction. Which really is about how exceptions are handled, not the exceptions themselves, and nothing different from other exceptions.
Similarly, Infinity and +Infinity are elements of numeric type arising in the extension of the real line but they are not real numbers. Mathematically, they can be represented by sequences of real numbers converging to either + or -Infinity.
Javascript uses NaN to represent anything it encounters that can't be represented any other way by its specifications. It does not mean it is not a number. It's just the easiest way to describe the encounter. NaN means that it or an object that refers to it could not be represented in any other way by javascript. For all practical purposes, it is 'unknown'. Being 'unknown' it cannot tell you what it is nor even if it is itself. It is not even the object it is assigned to. It can only tell you what it is not, and not-ness or nothingness can only be described mathematically in a programming language. Since mathematics is about numbers, javascript represents nothingness as NaN. That doesn't mean it's not a number. It means we can't read it any other way that makes sense. That's why it can't even equal itself. Because it doesn't.
This is simply because NaN is a property of the Number object in JS, It has nothing to do with it being a number.
The best way to think of NAN is that its not a known number. Thats why NAN != NAN because each NAN value represents some unique unknown number. NANs are necessary because floating point numbers have a limited range of values. In some cases rounding occurs where the lower bits are lost which leads to what appears to be nonsense like 1.0/11*11 != 1.0. Really large values which are greater are NANs with infinity being a perfect example.
Given we only have ten fingers any attempt to show values greater than 10 are impossible, which means such values must be NANs because we have lost the true value of this greater than 10 value. The same is true of floating point values, where the value exceeds the limits of what can be held in a float.
NaN is still a numeric type, but it represents value that could not represent a valid number.
Because NaN is a numeric data type.
NaN is a number from a type point of view, but is not a normal number like 1, 2 or 329131. The name "Not A Number" refers to the fact that the value represented is special and is about the IEEE format spec domain, not javascript language domain.
If using jQuery, I prefer isNumeric over checking the type:
console.log($.isNumeric(NaN)); // returns false
console.log($.type(NaN)); // returns number
http://api.jquery.com/jQuery.isNumeric/
Javascript has only one numeric data type, which is the standard 64-bit double-precision float. Everything is a double. NaN is a special value of double, but it's a double nonetheless.
All that parseInt does is to "cast" your string into a numeric data type, so the result is always "number"; only if the original string wasn't parseable, its value will be NaN.
We could argue that NaN is a special case object. In this case, NaN's object represents a number that makes no mathematical sense. There are some other special case objects in math like INFINITE and so on.
You can still do some calculations with it, but that will yield strange behaviours.
More info here: http://www.concentric.net/~ttwang/tech/javafloat.htm (java based, not javascript)
You've got to love Javascript. It has some interesting little quirks.
http://wtfjs.com/page/13
Most of those quirks can be explained if you stop to work them out logically, or if you know a bit about number theory, but nevertheless they can still catch you out if you don't know about them.
By the way, I recommend reading the rest of http://wtfjs.com/ -- there's a lot more interesting quirks than this one to be found!
The value NaN is really the Number.NaN hence when you ask if it is a number it will say yes. You did the correct thing by using the isNaN() call.
For information, NaN can also be returned by operations on Numbers that are not defined like divisions by zero or square root of a negative number.
It is special value of Number type as POSITIVE_INFINITY
Why? By design
An example
Imagine We are converting a string to a number:
Number("string"); // returns NaN
We changed the data type to number but its value is not a number!

Categories

Resources