Why javascript's typeof always return "object"?

38,095

Solution 1

JS's typeof doesn't always return 'object', but it does return object for things which people may not consider to be objects -- ie arrays, and also, oddly, for nulls.

For arrays this is correct, because as far as JS is concerned, arrays are objects; they're the same thing. Array is just another class, and you can instantiate objects of type Array, but they're still treated as objects.

This page has a list of types in JS, along with the response you'll get for each of them from typeof. It also has some JS code to override the typeof function with one that returns more useful information. If you're worried about it not being useful, you could implement something like that if you wish.

Solution 2

It doesn't always return "object":

alert(typeof "hello");

That said, a (possibly) more useful trick to examine objects is to use Object.prototype.toString.call() and look at the result:

var t = Object.prototype.toString.call(itIsAMystery);

That will give you a string like [object Foo] with "Foo" being the constructor (I think) the interesting part. For "native" types (like Date or String) you get back that constructor name.

Solution 3

In my experience, the main problem with typeof comes from distinguishing between arrays, objects, and nulls (all return "object").

To do this, I first check typeof then I check the null case or the "object's" constructor, like this:

for (o in obj) {
    if (obj.hasOwnProperty(o)) {
        switch (typeof obj[o]) {
            case "object":
                if (obj[o] === null) {
                    //do somethign with null
                } else {
                    if (obj[o].constructor.name === "Array") {
                        //do something with an Array
                    } else {
                        //do something with an Object
                    }
                }
                break;
            case "function":
                //do something with a function
                break;
            default:
                //do something with strings, booleans, numbers
                break;
        }
    }
}

Solution 4

Not all typeof returns objects.

Objects, Arrays and RegEx returns a type of object.

Function which is an object (reference type), yet returns type of function. That's an inconsistency in the language.

Another thing to note, undefined returns undefined while null returns object which is a bug in JS.

NaN (not a number) returns a type of number.

Better you keep track of all these and be aware of these strange behaviors.

For your reference here are all the type of values:

typeof "Tamal" ---> string
typeof 100 ---> number
typeof true ---> boolean
typeof false ---> boolean
typeof undefined ---> undefined
typeof function() {} ---> function
typeof Symbol() ---> symbol
typeof {name: "Tamal"} ---> object
typeof [1, 2, 3] ---> object
typeof /^/ ---> object
typeof NaN ---> number
typeof null ---> object (bug)

Solution 5

To add in with the others, typeof returns both objects and primitives. There are 5 primitive types in javascript: undefined, null, boolean, string and number. All else is an object. When typeof is applied to any object type other than Function, it simply returns “object”. When applied to a function, it returns a function object.

So, for example:

  • typeof true; //returns the primitive type "boolean"
  • typeof 123; //returns the primitive type "number"
  • typeof null //returns "object" which is a mistake, but so far there is no fix in another ECMAScript version, just talk about doing so.
  • typeof object //returns "object", which makes sense

To expound further on Pointy's answer, there is in every JavaScript object an internal property known as [[Class]] in ECMAScript 5. In order to display the actual value of the object, you can reference the [[Class]] property using: Object.prototype.toString. To avoid some of the specialized built-in objects overwriting toString you use the internal method of Call that will reveal the actual object type.

So instead of getting the generic object back from toString:

var dateObject = Object.prototype.toString(new Date);
document.write(dateObject);//[object Object]

You can get the actual object type using Call:

var dateObject = Object.prototype.toString.call(new Date);
document.write(dateObject);//[object Date]
Share:
38,095
The Student
Author by

The Student

Updated on August 10, 2022

Comments

  • The Student
    The Student almost 2 years

    What's it used for if it always returns object as type?

    always for Elements or lists.