Why does jsonb use more space for storing integers?
It's simple. JSON doesn't have a concept of an integer, only a "number". From the docs


  When converting textual JSON input into jsonb, the primitive types described by RFC 7159 are effectively mapped onto native PostgreSQL types, as shown in Table 8-23.


That table shows a JSON "number" is mapped to a numeric. The max precision on numeric is 


  up to 131072 digits before the decimal point; up to 16383 digits after the decimal point


However, I don't think it actually stores that. It does store a numeric of some sort. The numeric source is quite frankly kind of difficult to follow.

Using an array of smallint is clearly better if it fits your workload. It has less wasted space for packing, and less wasted space for the data itself. smallint[] however


Does not support the same range of numbers.
Does not support embedding different types.
Does not support any precision at all.
Does not exchange well with web-clients.