4 ms·
> You can also use the unary + operator to convert values to numbers: + "42"; // 42 > [...] However the "+" operator simply converts the string to NaN if
by gildas 11y ago
> You can also use the unary + operator to convert values to numbers:
+ "42"; // 42
> [...] However the "+" operator simply converts the string to NaN if there is any invalid character in it.
Being a bit pedantic here, why not recommending the Number function which may be less obscure for beginners?
Number("42"); // 42
- arcatek 11y agothe String function is also a nice way to cast a value to a string (using .toString() is unsafe because it may not exist, such as with undefined and null): String(42) === "42". An other thing that could maybe be covered is this specifity: typeof "42" === "string" typeof String(42) === "string" typeof new String(42) === "object" Native constructors are ... fun beasts, to say the least.
- serve_yay 11y agoYes, that's a good suggestion. Boolean works as well, for coercing to boolean of course.
- ahoge 11y agoSince calling constructor functions without `new` is generally an error, I'd rather use `parseFloat`.
- serve_yay 11y ago> Since calling constructor functions without `new` is generally an error The behavior of Number, Boolean, String, and Array is well-defined, it's safe to call them without new. In fact, in the case of String/Boolean/Number, calling them with new will often do something you don't expect. (Calling them with new gives you a Number/String/Boolean object, not primitive, which can cause trouble when you try to compare them with ===, unless you remember to use their `valueOf` method) Also, as noted below, it's possible for objects to not have a `toString` method, so attempting to call it to get the object's value as a string could blow up. So it's actually safer to coerce to string by adding an empty string or passing to String().
- ahoge 11y ago> The behavior of Number, Boolean, String, and Array is well-defined, it's safe to call them without new. ES6 is packed with weird but well-defined things. The problem is that calling a constructor function (a PascalCase'd function) without `new` looks like an error because it generally is an error. To make matters worse, without closely examining that function, you cannot tell if it's an error. I do know that `Number()` happens to be one of those constructor functions which not only work without `new`, it also happens to behave differently when `new` is missing. It does not return an object. It returns a primitive. Someone who doesn't know about this unusual secondary function will waste some time if they spot this apparent mistake. Now, to defuse this time-wasting trap, you could either add a comment... or just do the sensible thing and write it in a way which does not require a comment.
- serve_yay 11y agoThat's fair, I just find them super useful in various situations, for example filtering over an array with Boolean to remove falsey values.
- bluesnowmonkey 11y agoAnother way to cast to a Number is the bitwise-or operator. It has the useful property of always yielding a number. '42' | 0; // 42 NaN | 0; // 0 null | 0; // 0 undefined | 0; // 0 false | 0; // 0 true | 0; // 1
- Bahamut 11y agoCorrect me if I'm wrong, but I thought that the unary operator and the Number constructor yield equivalent results?
- amelius 11y agoBecause Number(...) uses more bytes on the wire.
- hajile 11y agoNumber() also converts to NaN if it's not a number though I would still avoid the + operator here because it is code smell (looks like you forgot your variable to concat). Number automatically accepts exponent notation and auto-converts to hex (ignoring octal). parseInt() auto-converts hex and octal unless a radix is specified, but it also ignores the remaining non-number characters at the end of the string. There isn't a single method that does whatever you want.
- tracker1 11y agoIf you use a double NOT ~~"foo" you will always get a finite int32 value... which is useful when you can use 0 as a "default" representation. For that matter, all bitwise operations will coerce a value to an int32 representation. Which is something to be aware of, if you want larger integer values (< 2^53 - 1 and > -2^53 + 1).