rmoestl
rmoestl

Reputation: 3155

Any caveats using isPrototypeOf in JavaScript to check if a variable is of a specific type?

What I want to do

I'd like to write a function that is able to deal with two different argument types as its first parameter.

To be more specific, the function shall be able to deal with the first argument either being NodeList or Element.

My research

I was researching a bit on how to detect the type of a variable, since I'm not using libraries like jQuery or underscore and came across a variety of resources. Those were the best:

I didn't expect that this particular corner of JavaScript is this flawed. The resources above list ways of doing this with typeof, instanceof etc.

But none of the resources I've found included isPrototypeOf as a viable option.

The question

I found NodeList.prototype.isPrototypeOf(myParam) and Element.prototype.isPrototypeOf(myParam) to work quite well. Since none of the resources I've found discusses the usage of isPrototypeOf, I'm wondering:

Are there any caveats using isPrototypeOf to check a variable for a specific type?

Upvotes: 3

Views: 345

Answers (2)

Dan0
Dan0

Reputation: 107

A caveat is you can't use isPrototypeOf on primitive values (numbers, strings, booleans) because they aren't objects. Primitives MDN

console.log(String.prototype.isPrototypeOf('I am string')); // false
console.log(Number.prototype.isPrototypeOf(1)); // false
console.log(Boolean.prototype.isPrototypeOf(true)); // false

Another caveat is many things are prototypes of an Object, like Arrays, Functions, Regular Expressions, Dates, even Elements

console.log(Object.prototype.isPrototypeOf([])); // true
console.log(Object.prototype.isPrototypeOf(function(){})); // true
console.log(Object.prototype.isPrototypeOf(/test/i)); // true
console.log(Object.prototype.isPrototypeOf(new Date())); // true
console.log(Object.prototype.isPrototypeOf(document.querySelector('body'))); // true

Todd Motto has a nice solution for reliable type checking Primitives and Global Objects.

function type(obj) {
  return Object.prototype.toString.call(obj).slice(8, -1);
}

However, this doesn't work if checking that a value is an Element or NodeList. For that isPrototypeOf works well.

Upvotes: 0

Andriy Ivaneyko
Andriy Ivaneyko

Reputation: 22021

My guess there are no any caveats with using isPrototypeOf. However you aren't always able to use isinstanceof. If you have no constructor function and use Object.create you cannot use isinstanceof to check whether object belongs to prototype. However you would always be able to use isPrototypeOf to check it.

var proto = {
    // some properties
}
var o = Object.create(proto);
console.log(proto.isPrototypeOf(o));
// true
console.log(o instanceof proto);   
// TypeError

Upvotes: 1

Related Questions