7

I came across the following table which states the internal [[Class]] property of an object and its corresponding value that the typeof operator returns.

Value               Class      Type
-------------------------------------
"foo"               String     string
new String("foo")   String     object
1.2                 Number     number
new Number(1.2)     Number     object
true                Boolean    boolean
new Boolean(true)   Boolean    object
new Date()          Date       object
new Error()         Error      object
[1,2,3]             Array      object
new Array(1, 2, 3)  Array      object
new Function("")    Function   function
/abc/g              RegExp     object (function in Nitro/V8)
new RegExp("meow")  RegExp     object (function in Nitro/V8)
{}                  Object     object
new Object()        Object     object

One thing to note here is the typeof correctly returns the primitive data types associated in Javascript.

However, it returns an object type for an array which inherits from the Array.prototype, but returns a function type for a function that is inheriting from the Function.prototype.

Given everything is an object in Javascript (including arrays, functions & primitive data type objects), I find this behaviour of the typeof operator very inconsistent.

Can someone throw some light on how the typeof operator works in reality?

nashcheez
  • 5,067
  • 1
  • 27
  • 53
  • you should consider **instanceof** when dealing with objects https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof – ymz Feb 16 '17 at 12:06
  • There are only certain types with specific result. Every other type is considered an object. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof – Armin Feb 16 '17 at 12:09
  • If typeof returned `object` for everything, since everything is an object in javascript, it would be totally useless. – Erich Kitzmueller Feb 16 '17 at 12:10
  • 1
    `typeof` is useful only when checking a non-declared variable. Use `Object.prototype.toString.call(type)` to get the "class". `type` here being whatever object or primitive you want to check. – Teemu Feb 16 '17 at 12:14
  • I recall asking this once, it was explained to me that typeof hails back to the origins of JS when a "typetag" is how you determined the typeof an object. This led to some peculiarities though, for instance, objects had "0" as a typetag, but so did null, so "null" actually has a type. "document.all" is also "undefined" if I recall correctly, because you can't use one of the predefined type tags in custom objects. Checking the constructor, "type", or instanceof, I think are the preferred ways. Typeof can be useful but there's gotchas for sure. There was the old "arguments" array-not-array, etc. – Tim Consolazio Feb 16 '17 at 12:19
  • @TimConsolazio Yep, the roots are in the history of JS. Note, that `instanceof` is pretty much as useless as `typeof`. – Teemu Feb 16 '17 at 12:21
  • Yes, the usage of `typeof` is essentially to detect non-declared variables as @Teemu pointed out. However, why the anomaly in the return of a `function` & an `array`? Although `instanceof` returns the correct instance type for both, any reason as to why the preferential treatment for functions in a `typeof` would be the reason for my bewilderment here. – nashcheez Feb 16 '17 at 12:30
  • `instanceof` may return incorrect values when checking host objects. It is useful only when checking self-made objects. If you need the "class", always use the code in my first comment. It's well-known and widely used method for class checking. – Teemu Feb 16 '17 at 12:38
  • 1
    JS history Tim has referred is shortly explained in [this answer](http://stackoverflow.com/a/18808270). – Teemu Feb 16 '17 at 12:51
  • Is this operator an "internal function" like `alert()` or `prompt()`? –  May 24 '19 at 08:37

2 Answers2

5

This is slightly odd, idiosyncratic Javascript behaviour. It's inherited from the earliest days of Javascript and probably would not be written in such a way today.

Nonetheless, we are where we are with Javascript, so we have to deal with it!

The thing is that values in Javascript are either objects or they are primitives. This is a design decision. They cannot be anything else. The types of primitives are:

  • strings
  • numbers
  • booleans
  • symbols (from ES2015)
  • the special value undefined
  • the special value null (for which typeof also returns object)

Anything and everything else is an object. This is by design. Arrays are objects, so typeof returns object, as does every other object that is not callable (i.e. a function). See the spec for typeof.

The better question is to ask why you want to test if something is an array. You probably don't need to, especially as array-like objects such as NodeLists are not arrays but are like them in many ways.

The best solution in most cases is to call Array.from on the value supplied: then you know that it is an array.

lonesomeday
  • 233,373
  • 50
  • 316
  • 318
  • To test an array I could rather use `Array.isArray()` or `instanceof`. Just wondering why the anomaly of return type for functions and arrays. – nashcheez Feb 16 '17 at 12:35
  • @nashcheez The answer is the historical decision that arrays are not primitives. – lonesomeday Feb 16 '17 at 12:38
-2

Use typeof operator in JavaScript

'Typeof' is an operator which is used to return a string description of the type of a variable.

Example

console.log(typeof 42);
 output: "number"

console.log(typeof true);
 output: "boolean"
Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
Arun
  • 63
  • 1
  • 4