My JavaScript book is out! Don't miss the opportunity to upgrade your beginner or average dev skills.

Sunday, October 09, 2011

A Better is_a Function for JS

In 2007 I have posted about get_class and is_a functions in JavaScript in order to simulate original PHP functions.

Well ... that was crap, since a much simpler and meaningful version of the is_a function can be easily summarized like this:

var is_a = function () {
function verify(what) {
// implicit objet representation
// the way to test primitives too
return this instanceof what;
}
return function is_a(who, what) {
// only undefined and null
// return always false
return who == null ?
false :
verify.call(who, what)
;
};
}();

... or even smaller with explicit cast ...

function is_a(who, what) {
// only undefined and null
// return always false
return who == null ?
false :
Object(who) instanceof what
;
}

An "even smaller" alternative via @kentaromiura

function is_a(who, what) {
return who != null && Object(who) instanceof what;
}


Here a usage example:

alert([
is_a(false, Boolean), // true
is_a("", String), // true
is_a(123, Number), // true
is_a(/r/, RegExp), // true
is_a([], Array), // true
is_a(null, Object), // false
is_a(undefined, Object) // false
]);

As twitted few minutes ago, an alternative would be to pollute the Object.prototype:

Object.defineProperty(Object.prototype, "is_a", {
value: function (constructor) {
return this instanceof constructor;
}
});

// (123).is_a(Number); // true

However, this way would not scale with null and undefined so that per each test we need to check them and this is boring.
Finally, I would not worry about cross frame variables since via postMessage everything has to be serialized and unserialized.

3 comments:

Anonymous said...

Everything (except null and undefined) is an instance of Object.

Andrea Giammarchi said...

correct, if you consider that once inside their prototype they are all instance of objects.

Boolean.prototype.isObject = function () {
return this instanceof Object &&
this instanceof Boolean;
};

false.isObject(); // true

Raynos said...

When polluting the object.prototype please set configurable to true so the property can be deleted.