简体   繁体   中英

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 beingNodeList 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?

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM