Pragmatic types: is JavaScript an untyped language?

stereobooster - Aug 23 '18 - - Dev Community

I've found that some people call JavaScript a "dynamically, weakly typed" language, but some even say "untyped"? Which is it really?

-- https://stackoverflow.com/questions/964910/is-javascript-an-untyped-language

To answer the question we need to define what is "untyped", what is "dynamically" and "weakly" typed languages are - read the full post on the subject "Dynamically-, statically-, gradually-, weakly-, strongly- and un-typed languages". If you decided to skip it:

  • Untyped - language with one type, like assembly language which works with the only one type - bit strings.
  • Dynamically typed or better to say dynamically-checked types - language in which types get checked at runtime.
  • Weakly typed - this term doesn't have an exact meaning, so I advise to avoid it, but most likely people refer to JavaScript's implicit coercions, which make types look "weak".

JS and types

There are seven possible values that typeof returns: "number," "string," "boolean," "object," "function," "undefined," and "unknown". Also, we can check if values are an instance of some type like this:

date instanceof Date

or like this

Object.prototype.toString.call(date) === '[object Date]'

No, JS is not untyped. It has more than one type.

Is JavaScript a dynamically typed language?

Type checking "performed by system" at runtime:

undefined()
VM308:1 Uncaught TypeError: undefined is not a function
    at <anonymous>:1:1

Type checking "performed by programmer" at runtime:

if (typeof x === "string")

Yes, JS is dynamically typed.

Why people get so confused about this subject?

JS goes an extra mile to pretend it doesn't have types or type errors.

What type errors exist in JS?

When you try to use non-function value as a function

undefined()
VM308:1 Uncaught TypeError: undefined is not a function
    at <anonymous>:1:1

When you try to access a property of undefined or null value.
Other values considered to be an object and if you access an inexisting value of an object you will get undefined instead of type error. This is hidden type error.

null.test
VM84:1 Uncaught TypeError: Cannot read property 'test' of null
    at <anonymous>:1:1
undefined.test
VM134:1 Uncaught TypeError: Cannot read property 'test' of undefined
    at <anonymous>:1:1

Arithmetic operations on non-number values result in NaN, which is the JS way to express TypeErrors about arithmetic operations

1 * {}
NaN

Coercion

Coercion can be convenient when you do not need explicitly convert from integers to floating point numbers in arithmetic operations, but in JS coercion used to hide type errors.

1*"1" // result 1, should be type error
1+"1" // result "11", should be type error
1*[] // result 0, should be type error
1+[] // result "1", should be type error
"1"+[] // result "1", should be type error

JS tries to hide type errors so hard, that it resulted in obscure coercion rules.

source

There a lot of research on that matter:

Inconsistent types

JS have bugs in type operators which are preserved until now for compatibility reasons. For example:

typeof null
"object"
typeof document.all
"undefined"

Bugs in type operators and obscure coercion rules make an impression that there is no way such language have types.

Final conclusion

JS has types, JS has type errors even so it tries to hide most of them, JS can check types at runtime. JS is dynamically typed language.

This post is part of the series. Follow me on twitter and github.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .