I was perusing the underscore.js library and I found something I haven't come across before:
if (obj.length === +obj.length) { ... }
What is that +
operator doing there? For context, here is a direct link to that part of the file.
I was perusing the underscore.js library and I found something I haven't come across before:
if (obj.length === +obj.length) { ... }
What is that +
operator doing there? For context, here is a direct link to that part of the file.
The unary +
operator can be used to convert a value to a number in JavaScript. Underscore appears to be testing that the .length
property is a number, otherwise it won't be equal to itself-converted-to-a-number.
According to MDN:
The unary plus operator precedes its operand and evaluates to its operand but attempts to converts it into a number, if it isn't already. For example, y = +x takes the value of x and assigns that to y; that is, if x were 3, y would get the value 3 and x would retain the value 3; but if x were the string "3", y would also get the value 3. Although unary negation (-) also can convert non-numbers, unary plus is the fastest and preferred way of converting something into a number, because it does not perform any other operations on the number. It 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 ("0x"-prefixed) formats are supported. Negative numbers are supported (though not for hex). If it cannot parse a particular value, it will evaluate to NaN.
It's a way of ensuring that obj.length is a number rather than a potential string. The reason for this is that the === will fail if the length (for whatever reason) is a string variable, e.g. "3".
It's a nice hack to check whether obj.length
is of the type number
or not. You see, the +
operator can be used for string coercion. For example:
alert(+ "3" + 7); // alerts 10
This is possible because the +
operator coerces the string "3"
to the number 3
. Hence the result is 10
and not "37"
.
In addition, JavaScript has two types of equality and inequality operators:
3 === "3"
expresses false).3 == "3"
expresses true).Strict equality and inequality doesn't coerce the value. Hence the number 3
is not equal to the string "3"
. Normal equality and inequality does coerce the value. Hence the number 3
is equal to the string "3"
.
Now, the above code simply coerces obj.length
to a number using the +
operator, and strictly checks whether the value before and after the coercion are the same (i.e. obj.length
of the type number
). It's logically equivalent to the following code (only more succinct):
if (typeof obj.length === "number") {
// code
}