Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why using the unary operator + on an array gives inconsistent results in javascript?

I was doing some testing converting values to integer in javascript and printing the output in the console when I came across with this strange behavior.

console.log(+[]) ==> 0
console.log(+[123]) ==> 123
console.log(+['123']) ==> 123
console.log(+[123, 456]) ==> NaN
console.log(+['123asdf']) ==> NaN

I thought the values were being converted using parseInt but turns out it wasn't so I went to the javascript conversion table http://www.w3schools.com/js/js_type_conversion.asp

This give me a better idea on how conversions are performed. Acording to this table

[] => 0
[20] => 20
[10,20] => NaN
["twenty"] =>NaN
["ten","twenty"] => NaN

So aparently they take the first value of the array and convert it using the specified rules. The rules of parseInt does not apply.

I tested to reach this conclusion. You can nested it all you want, it will give you the same result.

console.log(+[[[[[[[[[[[10]]]]]]]]]]]) => 10

So then I thought, ok if that's the case

console.log(+[undefined]) will return NaN
console.log(+[null]) will return 0
console.log(+[false]) will return 0

those are the values expected from the javascript conversion table to integer but turns out

console.log(+[undefined]) => 0
console.log(+[null]) => 0
console.log(+[false]) => NaN

The last is the most strange because false is converted to 0, not to NaN. Can someone explain the strange behaviour or explain how this conversion is performed?

like image 508
devconcept Avatar asked May 19 '15 12:05

devconcept


People also ask

What is the unary operator in JavaScript?

The unary plus operator ( + ) precedes its operand and evaluates to its operand but attempts to convert it into a number, if it isn't already.

What does the unary operator typeof return?

It returns the data type of the operand in string format. The typeof operator is used as a prefix(typeof operand). Above, we applied the typeof operator on the myName variable and log it on the console. As a result, we printed string on the console because the data type of the myName variable is a string.

What does unary plus operator do to string representations of integers?

The Unary (+) can convert string representations of integers and floats, as well as the non-string values true, false, and null. Integers in both decimal and hexadecimal formats are supported. Negative numbers are supported (though not for hex). If it cannot parse a particular value, it will evaluate to NaN.

How many operands are associated with a unary operator?

Unary operators act on only one operand in an expression.


1 Answers

The Unary + operator internally uses the ToNumber abstract operation.

The ToNumber abstract operation, when applied to objects, calls the object's toString method (by way of the [[DefaultValue]] internal method) and then re-applies the ToNumber operation on the resulting string representation.

The interesting thing here is Array's toString method. Note that [false].toString() is quite different from [undefined].toString() or [null].toString(). When we inspect the specification for Array.prototype.toString, we see that internally it uses Array.prototype.join. Step 8 of the join algorithm says:

  1. If element0 is undefined or null, let R be the empty String; otherwise, Let R be ToString(element0).

Thus, any array containing a single null or undefined stringifies to the empty string (which ToNumber number-ifies to 0), while other values will stringify to some other string (which will then number-ify to NaN if the string is non-numeric).

+[undefined] is the same as +"", while +[false] is the same as +"false".

like image 78
apsillers Avatar answered Sep 29 '22 11:09

apsillers