Reputation: 1301
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
Reputation: 8798
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.")
}
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
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
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