Skip to content

Conversation

wjcrowcroft
Copy link

Adds _.toType() method, borrowed from Angus Croll's article on "Fixing the JavaScript typeof operator" (http://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/). Includes some tests, too.

Normally I only ever use typeof whatever !== "undefined" since as Angus points out, typeof is pretty useless for many other cases, for example:

typeof null; // "object"
typeof {a: 4}; // "object"
typeof [1, 2, 3]; // "object"
(function() { return typeof arguments })(); // "object"
typeof new ReferenceError; // "object"
typeof new Date; // "object"
typeof /a-z/; // "object"
typeof Math; // "object"
typeof JSON; // "object"
typeof new Number(4); // "object"
typeof new String("abc"); // "object"
typeof new Boolean(true); // "object"

vs:

_.toType({a: 4}); // "Object"
_.toType([1, 2, 3]); // "Array"
(function() { return _.toType(arguments) })(); // "Arguments"
_.toType(new ReferenceError); // "Error"
_.toType(new Date); // "Date"
_.toType(/a-z/); // "RegExp"
_.toType(Math); // "Math"
_.toType(JSON); // "JSON"
_.toType(new Number(4)); // "Number"
_.toType(new String("abc")); // "String"
_.toType(new Boolean(true)); // "Boolean"

NB. It might make more sense to return types as lowercase in some scenarios (for example "Undefined" or "Null", or where the difference between "string" and "String" might cause issues) - not sure really. Perhaps the function could return lowercase by default, and add an option eg. preserveCase = preserveCase || false

@OnesimusUnbound
Copy link

Add a test case for Function type, something like ok(_.toType(function(){}) === "Function", 'function(){} is a Function');. Anyway, I've test it and it's working.

@wjcrowcroft
Copy link
Author

Re: above commit, adds two more tests for Function types.

@michaelficarra
Copy link
Collaborator

Can you produce a use case for this? I'm failing to see how this is useful considering underscore already has the various _.isX methods. You say this "fixes" typeof, but typeof only has two valid uses, one of which can't be emulated (testing if a variable has been declared without throwing a ReferenceError) and another (existence of [[Call]]) which is already covered by _.isFunction ... mostly (at least as well as this would cover it).

edit: Oh, I see. I should have looked at the code. You're just pulling the [[Class]]. And what practical use does that have?

@jashkenas
Copy link
Owner

Yep -- I'm afraid this method goes almost entirely counter to the spirit of Underscore: Looking for explicit types is a fool's game in JavaScript, because they're very weak (new Number vs. 5), and good for almost nothing.

If you want to dispatch differently based on the type being passed as an argument to a function ... just check for that type: which the _.is[Type] family of functions is already able to do far more efficiently than a toString test.

@jashkenas jashkenas closed this Aug 10, 2011
@wjcrowcroft
Copy link
Author

Fair play, cheers for the feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants