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.