cubefox
cubefox

Reputation: 1301

what is the shortest way to check for typeof any type?

I found this today to check if something is a boolean:

Instead of:

typeof a === 'boolean' && //do sth

You can use:

a === !!a && //do sth

Are there any other methods like this to check for typeof string/number/obj/arr etc?

I'm not looking for best practices but rather for clever ways to do " typechecking " .

Upvotes: 1

Views: 2587

Answers (3)

Calvintwr
Calvintwr

Reputation: 8798

A clean approach

You can't do it cleanly. Javascript has a few quirks that I see almost always throws people off, even the most experience. And very often you end up with very ugly, not really human readable conditional statements:

if (
    typeof foo !== 'string'
    || (typeof foo !== 'number'
    || (typeof foo === 'number' && !isNaN(chk)))
    || !Array.isArray(chk)
) {

    throw Error("Not valid, but I don't know why.")
}

No other way, just use a very lightweight library

You should consider using a very small library like Issable. Solves all problems:

let integer = 10
let array = []
is(integer).number() // returns true
is(array).number() // throws error

If you make it a habit, your code will be much stronger. Typescript solves part of the problem but doesn't work at runtime, which is also important.

function test (string, boolean) {
    // any of these below will throw errors to protect you
    is(string).string()
    is(boolean).boolean()
    // continue with your code.
}

Upvotes: 0

Joey Phillips
Joey Phillips

Reputation: 1625

Types in javascript are not that simple but this is a great guide for you!

Checking types in Javascript is a big mess.

typeof operator

In the beginning, there was typeof. This handy operator gives you the "type" of a Javascript value:

typeof 3 // "number" 
typeof "abc" // "string"
 typeof {} // "object"
 typeof true // "boolean" 
typeof undefined // "undefined" 
typeof function(){} // "function" 

All is fine 'n dandy until

typeof [] // "object" 

Huh? An array's type is object? I guess it is, if you want to get technical about it, but still, what the...

typeof null // "object" 

Okay, now that's just wrong!

instanceof operator

The instanceof operator tells you whether a object is an instance of a certain type. The so-called "type" is a constructor. For example

function Animal(){}
    var a = new Animal()
    a instanceof Animal // true

Cross-window Issues of instanceof

It turns out that instanceof has another problem. It breaks down when you try to test an object coming from another window. You know? The ones that are created for each , or popup window that you create.

   var iframe = document.createElement('iframe')
    document.body.appendChild(iframe)
    var iWindow = iframe.contentWindow // get a reference to the window object of the iframe
    iWindow.document.write('<script>var arr = [1, 2, 3]</script>') // create an array var in iframe's window
    iWindow.arr // [1, 2, 3]
    iWindow.arr instanceof Array // false

Duck-Typing

Because neither typeof or instanceof are satisfactory, many resort to duck-typing. This means checking the behavior: if it looks like a duck and quacks like a duck, then it is a duck as far as I am concerned. Pretty sure I misquoted that...oh well.

So, using duck-typing, an isArray check might look like

// source: http://forums.devshed.com/javascript-development-115/javascript-test-whether-a-variable-is-array-or-not-33051.html
function isArray(obj){
    return (typeof(obj.length)=="undefined") ?
        false:true;
}

Object.prototype.toString method

It turns out that, you can get type information about an object by using the Object.prototype.toString method.

Object.prototype.toString.call(3) // "[object Number]"
Object.prototype.toString.call([1, 2, 3]) // "[object Array]"
Object.prototype.toString.call({}) // "[object Object]"

Function.prototype.toString method

Yet another way to test for type information is by using the Function.prototype.toString method.

Function.prototype.toString.call((3).constructor)
// "function Number() {
//    [native code]
// }"

DOM Elements and Host Objects

So far, I have not mentioned type checking for DOM elements and host objects. That's because it's hard. With the exception of duck-typing, none of the methods mentioned above will work for all browsers. If you drop IE7 and below, however, you can actually get some of the things to work. The output below were created using Tutti

var div = document.createElement('div')
typeof div
Safari 5.0 => object
Firefox 3.6 => object
IE 7.0 => object
IE 8.0 => object
Opera 11.01 => object
div instanceof Element
Safari 5.0 => true
Firefox 3.6 => true
IE 7.0 => Error: 'Element' is undefined
IE 8.0 => true
Opera 11.01 => true
div instanceof HTMLDivElement
Safari 5.0 => true
Firefox 3.6 => true
IE 8.0 => true
IE 7.0 => Error: 'HTMLDivElement' is undefined
Opera 11.01 => true

http://tobyho.com/2011/01/28/checking-types-in-javascript/

Upvotes: 5

T.J. Crowder
T.J. Crowder

Reputation: 1074365

A very similar concept applies to all the fundamental types, but involving a function call and possibly more work than just boolean negation like your boolean example:

// String
a === String(a)

// Number
n === +n  // **FAILS** if `a` is `NaN` (which is `typeof "number"`)
Object.is(n, +n) // Works even if it is, but 0 and -0 are considered different

// Object (including arrays)
o === Object(o)

That last works because Object returns the object you call it with, if you call it with an object (it doesn't create a new one).


I know you've said you're intersted in tricks and not best practices, but...in general, I wouldn't do the above. I'd use typeof if I cared about the type and didn't know what it was, or conversion if I wanted a specific destination type and didn't know what type the input was.

Upvotes: 1

Related Questions