Is Number.isInteger inconsistent?

Number.isInteger(1) // output: true
Number.isInteger(new Number(1)) // output: false

but

Array.isArray([]) // output: true
Array.isArray(new Array()) // output: true

Is it just me or would Number.isInteger be more consistent if Number.isInteger(new Number(1)) === true?

This isn't inconsistent because [] and new Array() are identical (just the former is preferred), whereas 1 is a primitive but new Number(1) or Object(1) are objects. You can compare their typeof values as well.

1 Like

Yeah but the Number.isInteger could also check if the passed value is an instance of Number and then if value.valueOf() is an integer.
isInteger does as far as I know not have not to check if it is a primitive number type or not.

And in what case is Number(1) not supposed to be an integer?
If that works

const n = new Number(1)
console.log(n + 1) // output: 2

then it should be definitely recognized as an integer.

If you want to check whether things are integers after being coerced to a number, then just write Number.isInteger(+x) or Number.isInteger(Number(x)). There's no good reason why isInteger should implicitly do this on its own. Notice there are lots of values other than new Number instances where this would evaluate to true, many of which you would normally not consider to "be an integer".

Ok, I understand that. Just out of curiosity: what other values would evaluate to true not being a number primitive or a number instance calling valueOf() ?

Despite the best practice being to avoid creating boxed primitives, I've written a number of packages for working with them; for example, https://www.npmjs.com/package/is-number-object returns true for both primitive and boxed numbers; https://www.npmjs.com/package/unbox-primitive gets a primitive value from a boxed primitive without using + (which would coerce non-boxed-numbers to a number as well).

You're right that Number.isInteger could unbox Number primitives and return true for those, but the designed (and now expected) contract for it is that it only returns true for x when typeof x === 'number' and when x is a finite integer. Changing that now would likely break the web.