When, if ever, could Javascript's "typeof" return an incorrect type?

javascript

Solution

Remember: `typeof` is for literals.

typeof undefined === "undefined"
typeof 5 === "number"
typeof true === "boolean"
typeof "" === "string"
typeof {} === "object"
typeof [] === "object"
typeof function { } === "function"

// null is a weird exception:
typeof null === "object"

`instanceof` distinguishes when something is "of a Function" (notice that where typeof checks against string `"object"` instanceof checks against Function `Object` itself:

{} instanceof Object

function {} instanceof Object
function {} instanceof Function

[] instanceof Object
[] instanceof Array

As you see, typeof says `=== "function"` and `!== "object"`: this can be misleading, because a function is also an object. This is when instanceof comes into play.

Now, when you write a constructor, the constructed object is also instanceof your function:

// the constructor
function Example { }

// the object
var ex = new Example();

typeof Example === "function"
typeof ex === "object"
ex instanceof Object
ex instanceof Example

Using prototype you can also extend the chain, where typeof always says object:

function DerivedExample { }

DerivedExample.prototype = new Example();
// DerivedExample.prototype.constructor = DerivedExample;

var ex1 = new DerivedExample();

typeof DerivedExample === "function"
typeof ex1 === "object"
ex1 instanceof Object
ex1 instanceof Example
ex1 instanceof DerivedExample

So that's all about javaScript `typeof` and also `instanceof`. Hope it clarifies what's happening.

Something also good to know (this is not recommended to be used in production code, but i've seen in also in CoffeeScript source afair):

typeof new Number(5) === "object"
new Number(5) instanceof Object
new Number(5) instanceof Number

typeof new Boolean("true") === "object"
new Boolean("true") instanceof Object
new Boolean("true") instanceof Boolean

typeof new String("") === "object"
new String("") instanceof Object
new String("") instanceof String

About functions and the window object:

Every standalone function will be called in context of window. (Except) when you `"use strict"` "directive", a standalone function will be called with context of undefined.

function world() {
    // non-strict: this === window
    // use-strict: this === undefined
}
world();

Now when you write a function as a member of an object, the function's context is the object:

var hello = {
    world: function () {
        // this === hello
    }
};
hello.world();

This is also true for prototype functions, that are called in context of a newly constructed object:

function Hello() { }

Hello.prototype.world = function () {
    // this instanceof Hello
    // this will be === ex
};

var ex = new Hello();
ex.world();

And at least, you can change the context of any function using `call` and `apply`:

var ex = { };

function Example() {
    // (1) non-strict: this === window
    // (1) use-strict: this === undefined
    // (2) this === ex
}

Example(); // (1)
Example.call(ex);  // (2)
Example.apply(ex); // (2)

Problem

I am trying to work my way through someone else's code and am finding some bizarre things. I found the following code in part of the program: ``` if(typeof func == "function" || (typeof func == "object" && typeof func.document == "undefined")) { func(); } ``` This made no sense to me, as I wasn't sure when such an event could happen? Could typeof return the wrong type? Or is it possible for a non-function object to be callable? The code is a mess so I can't really find an example of where this particular check might succeed. I should note that the code may be upwards of 10 years old. The statement I received was that it was required because sometimes, when the code was originally written, a typeof was not returning function as a type. Also, this check was required because sometimes func would be passed a window object (?) so it was necessary to make sure it wasn't a window object as well.

Original source