Frostman
Frostman

Reputation: 53

Javascript Control many types with "typeof" without "if"

I was wondering if there is an alternative to the classic.

if (typeof firstPost === 'object' && typeof firstPost.active === 'boolean' && typeof firstPost.message === 'string' && typeof firstPost.maxHeight)

So as to avoid writing more code, maybe looping object.

Upvotes: 0

Views: 101

Answers (4)

Luca Rainone
Luca Rainone

Reputation: 16458

I would use this:

if this is user input

var firstPost = {
    active    : true,
    message   : "hello",
    maxHeight : 20
}

then:

var checks = {
    active    : 'boolean',
    message   : 'string',
    maxHeight : 'number'
}

try {
    for(var key in checks) {
        if(typeof firstPost[key] != checks[key]) {
            throw new Error(key + " is not " + checks[key]);
        }
    }
}catch(e) {
    alert(e.toString());
}

this is not bytesless, but it's more clean. (and it checks also if all keys are defined)

EDIT: There is no way more compact. However you can declare some function in another place and call it.

function checkObject(obj,checks) {
    for(var key in checks) {
        if(typeof obj[key] != checks[key]) {
            return false;
        }
    }
    return true;
} 

and simply

checkObject(firstPost,{
    active    : 'boolean',
    message   : 'string',
    maxHeight : 'number'
});

You can elaborate another return type in order to specify the error.

Upvotes: 2

Kaizo
Kaizo

Reputation: 4185

The first check can be simplified, because object instances are truthy !!{} === true, and you don't need to check specifically for object because you are checking if it has the properties later.

And most times you only need to know if there is data inside the object and not exactly if it is of a specific type:

function notUndef (aux) {
 return aux !== undefined;
}

if (firstPost && notUndef(firstPost.active) && notUdenf(firstPost.message) && notUndef(firstPost.maxHeight))

If you have a really long list of properties to check you can use a loop:

function checkHasProps (obj, properties) {
  obj || return false; 
  var hasAll = true;
  properties.forEach(function (prop) {
    if (obj[prop] === undefined) {
      hasAll = false;
    }
  });
  return hasAll;
}

if (checkHasProps(['active', 'message', 'maxHeight', (...)]));

And remember that typeof [] === 'object', so typeof is not a completly reliable way to check things.

Upvotes: 0

Oleg Novosad
Oleg Novosad

Reputation: 2421

Looping object or using another way will have more code than you wrote. Of course you can use "||" method to compare in javascript or kind of "? :" if else statement.

Upvotes: 0

Michael Kunst
Michael Kunst

Reputation: 2988

If there are always the same types and you're needing this exact if more often, you could wrap it in a function. Otherwise your if construct is the only real possibility you have I think. Of course you could create an object with the key as fieldname and the value as the required type, but I wouldn't do that, as it won't be easiliy readable anymore.

only thing that comes to my mind that would shorten this code (a little bit), is wrapping the typeof function into something like this:

function is(variable, type){
  return typeof variable == type;
}

So you could just call it like is(firstPost, 'object') and so on

Upvotes: 0

Related Questions