Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

javascript

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.

like image 626
ColdFrog Avatar asked Jan 30 '14 14:01

ColdFrog


People also ask

How do you check if there is an error in JS?

To check for javascript errors, simply open the console and look for the errors. It'll look something like this: Errors are generally marked in red or with a × . Any errors on your site have the potential to halt all other javascript execution, preventing other scripts from being able to run.

Should I use typeof or ===?

If typeof(typeof(x)) is always string, no matter what x actually is, then == should be sufficient and === unnecessary. The most efficient reason for not using typeof and rather the === operator would be for type coercion (interpretation) between browsers.

How do you avoid using a type in TypeScript?

any. ❌ Don't use any as a type unless you are in the process of migrating a JavaScript project to TypeScript. The compiler effectively treats any as “please turn off type checking for this thing”. It is similar to putting an @ts-ignore comment around every usage of the variable.

How do you return a type in TypeScript?

We can return any value from the function like string, number, any, character, etc. To define the return type for the function, we have to use the ':' symbol just after the parameter of the function and before the body of the function in TypeScript.


1 Answers

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)
like image 115
metadings Avatar answered Oct 01 '22 12:10

metadings