Previous | Current | Next |
---|---|---|
So, How Hard Do You Hit the Keyboard? | Type Coercion: The Sensible Bits | Type Coercion: The Mostly Sensible Bits |
Take this somewhat arbitrary snippet of JavaScript:
var strValue = "-1" // strValue is a character string
+strValue // Returns the numeric value -1
But wait a minute, strValue
is a character string, and everyone knows that character strings cannot necessarily be converted to numbers! This is quite correct; but in this case, JavaScript looks at the operation we want to perform and tries to be helpful…
The unary ^{1} +
operator attempts to return the numeric representation of its operand
Aside
Don’t be misled by the use of the “plus” symbol for this operator. This operator returns only the numeric value of its operand, not its positive numeric value
strValue
is the character string "-1"
+
operator now attempts to squeeze a numeric value out of the character string "-1"
"-1"
converts nicely to the numeric value -1
So, we can see that under the surface, JavaScript has automatically converted (or coerced) a character string into a number for us.
This is an example of where we explicitly instruct the coding to perform type coercion, because we expect to get a useful result.
But what about this situation:
var strValue = "cat" // strValue is a character string
+strValue // Returns the special value NaN (Not a number)
Sorry, not this time!
The logic of coding is exactly the same and all that has changed here is the value stored in variable strValue
is now "cat"
”, whereas before it was "-1"
—yet the result is completely different.
JavaScript went through exactly the same sequence of steps described above, but this time it discovered that the character string "cat"
has no numeric representation, so we got the correct, but possibly unexpected response of NaN
, or “Not a Number”.
So, type coercion does not always do either what you want or what you might expect.
+
OperatorSo, what would you expect to happen in this situation?
1 + 2 // 3 Trick question :-)
Here, we are using +
as the binary operator for arithmetic addition, and since both operands are numeric, everything is fine and we get the expect answer 3
.
But what happens in these situations?
1 + "2" // "12"
"3" + 4 // "34"
Buh!?
Here, we have a situation in which we are trying to perform the arithmetic operation add
on one or more non-numeric values.
In order for an arithmetic operation to be successful, both operands must be numeric.
Q: Is it safe simply to assume that both operands can be converted to numbers and then added?
A: It’s probably foolish to try to discover the numeric value of a "cat"
…
So JavaScript automatically and silently does two things here:
+
operator to perform string concatenation instead of arithmetic additionOperation coercion is also known as “overloading”. This is where the “+
” symbol switch operations from arithmetic addition to string concatenation depending on the data type of the arguments it receives.
Consequently, 1 + "2"
means that the numeric 1
is first converted to character "1"
, then "1"
and "2"
are concatenated giving "12"
.
The same process applies to "3" + 4
in order to give "34"
.
Ok, let’s mix it up a little more. What about this expression:
1 + 2 + "3" + 4 // "334"
What the flagnog!
To understand what’s going on here, let’s break this instruction down the way JavaScript sees it:
+
operator can only operate on two arguments at any one time1 + 2
) is a perfectly valid arithmetic operation, so addition is performed and the intermediate result 3
is substituted into the expression at this point3 + "3" + 4
3 + "3"
, but since one of the operands is a string, JavaScript converts the numeric operand value to a string, coerces the +
operator from arithmetic addition to string concatenation, and joins the two strings together giving another intermediate result of "33"
"33"
is then substituted back into the original expression to give "33" + 4
"334"
Let’s try these examples:
var boolVal1 = true
var boolVal2 = false
+boolVal1 // Numeric 1
+boolVal2 // Numeric 0
Again, we go through the same sequence of logic:
+
operator attempts to return the numeric representation of its operandboolVal1
and boolVal2
contain the values true
and false
thus making them both of type Boolean
true
and false
are represented by the single bits 1
and 0
respectively, and these convert directly to the integers 1
and 0
+true
is 1
and +false
is 0
Knowing then that Boolean values can be directly coerced to the integers 1
or 0
, the following statements now should make sense:
1 + true // 2
1 + false // 1
Ok, let’s try some examples the other way around:
var boolVal = false
var numVal = 2
!boolVal // true - no surprises here I hope
!numVal // false - hmmmm?
The logical NOT operator !
is another unary operator that expects a Boolean operand.
In the first example, there’s no problem because false
is a Boolean value and when the NOT operator is applied, we get the expected value of true
.
However, in the second example, !
has been passed an integer. So, before we can take the logical NOT of an integer, that integer must first be coerced to a Boolean value. The rule JavaScript follows is simply this: irrespective of their sign or magnitude, all non-zero numbers coerce to true
. Zero is the only number which coerces to false
.
Aside
JavaScript code minimizers seek to reduce your source code down to the smallest possible representation. In order to save a couple of bytes, they often use a trick that reduces the Boolean values
true
andfalse
from 4 or 5 bytes, down to 2.
!0
is used to representtrue
. Integer0
coerces tofalse
,!false
istrue
!1
is used to representfalse
. Integer1
coerces totrue
,!true
isfalse
So, both Boolean values can now be represented using only two characters
Here’s another type coercion trick that can be used if you have a loop that should stop after counting down to zero:
var n = 5;
while (n--) {
console.log(`Stop when n = 0. n is now ${n}`);
}
Here, we are relying on the fact that all non-zero integers coerce to true
; thus as long as n
remains greater than zero, the loop continues to run.
Stop when n = 0. n is now 4
Stop when n = 0. n is now 3
Stop when n = 0. n is now 2
Stop when n = 0. n is now 1
Stop when n = 0. n is now 0
As soon as n
becomes zero, zero coerces to false
and the loop terminates.
Previous | Current | Next |
---|---|---|
So, How Hard Do You Hit the Keyboard? | Type Coercion: The Sensible Bits | Type Coercion: The Mostly Sensible Bits |
Endnotes
1 An operator is said to be “unary” if it requires only one operand