Skip to content

Comment on A re-introduction to JavaScript

Comments

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

If 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).

Number() 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.

the 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.

Another 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

Bitwise operations don't produce Numbers (f64), but signed integers (i32).

produce...signed integers

Well, except for right logical shifts.

It always yields an integer, so it's useful if you know you want an integer.

Correct me if I'm wrong, but I thought that the unary operator and the Number constructor yield equivalent results?

Since calling constructor functions without `new` is generally an error, I'd rather use `parseFloat`.

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().

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.

That's fair, I just find them super useful in various situations, for example filtering over an array with Boolean to remove falsey values.

Yes, that's a good suggestion. Boolean works as well, for coercing to boolean of course.

Because Number(...) uses more bytes on the wire.

AboutSource Built by g1lg1l

Hackerly is an independent reader for Hacker News, built on the public HN API. Not affiliated with Y Combinator.