9

I understand why you need to use Object.prototype.toString() or String() for typechecking arrays, but isn't typeof sufficient for typechecking functions and strings? For example the polyfill on MDN for Array.isArray uses:

Object.prototype.toString.call(arg) == '[object Array]'; 

It's pretty clear in the case of arrays because you can't use typeof to check for arrays. Valentine uses instanceof for this:

ar instanceof Array 

But for strings/functions/booleans/numbers, why not use typeof?

jQuery and Underscore both use something like this to check for functions:

Object.prototype.toString.call(obj) == '[object Function]'; 

Isn't that equivalent to doing this?

typeof obj === 'function' 

or even this?

obj instanceof Function 

2 Answers 2

17

Ok I think I figured out why you see the toString usage. Consider this:

var toString = Object.prototype.toString; var strLit = 'example'; var strStr = String('example')​; var strObj = new String('example'); console.log(typeof strLit); // string console.log(typeof strStr); // string console.log(typeof strObj); // object console.log(strLit instanceof String); // false console.log(strStr instanceof String); // false console.log(strObj instanceof String); // true console.log(toString.call(strLit)); // [object String] console.log(toString.call(strStr)); // [object String] console.log(toString.call(strObj)); // [object String] 

Sign up to request clarification or add additional context in comments.

2 Comments

Do note that it does not work with Promises, at least in Chrome in Firefox. typeof mypromise === 'object, toString.call(mypromise) === '[Object]', but mypromise instanceof Promise === true
@Hurelu That makes sense because Promise inherits from Object. I get "[object Object]" using .call but if you do promise.toString it gives "[object Promise]". See stackoverflow.com/q/27746304/770127
1

The first reason I can think of is that typeof null returns object, which is not usually what you want (since null is not an object, but a type in its own right).

However, Object.prototype.toString.call(null) returns [object Null].

But, as you suggest, if you expect something to be a string or other type that works well with typeof, I see no reason why you can't use typeof (and I regularly do use typeof in that case).

Another reason libraries such as those you mention use their chosen method may simply be for consistency. You can use typeof to check for an Array, so use another method and stick to that throughout.

For some more information, Angus Croll has an excellent article on the typeof operator.

4 Comments

I'm talking about checking stuff the seemingly should work without a hitch like strings/functions/booleans/numbers
Do note that it does not work with Promises, at least in Chrome in firefox. typeof mypromise === 'object, toString.call(mypromise) === '[Object]', but mypromise instanceof Promise === true
@Hurelu - In latest stable Chrome I get "[object Promise]" for Object.prototype.toString.call(mypromise)
Funny. Just upgraded to Chrome 43.0.2357.81 and I still get [object Object]. I only checked through the console. I also checked again in Firefox and [object Promise] now comes correctly. Because of these mixed results, I would still caution against this method for detecting promises reliably.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.