'How does the prototype lookup work in isPrototypeOf on inherited classes?
Taking the following code as a starting point:
class SuperKlass {};
class SubKlass extends SuperKlass {};
const superKlass = new SuperKlass();
const subKlass = new SubKlass();
console.log(SuperKlass.isPrototypeOf(SubKlass));
console.log(SuperKlass.prototype.isPrototypeOf(subKlass));
console.log(SuperKlass.prototype.isPrototypeOf(SubKlass.prototype));
// true true true
How does the lookup work for each of these? For example, the definition of the method states:
The
isPrototypeOf()method checks if an object exists in another object's prototype chain.
So for the first one, SuperKlass.isPrototypeOf(SubKlass), SubKlass is the object whose prototype chain we are inspecting to find if it exists in SuperKlass. So then how does that work exactly? I tried debugging it a big in Chrome dev tools and figured it out on some trial-and-error for the first one:
When looking up the prototype chain does it use __proto__ or .prototype? And how would it work for the other two?
Solution 1:[1]
There are two important concepts here to understand Object.prototype.isPrototypeOf() :
- The prototype chain is traversed via
.__proto__, not via.prototype. - If the method call has the form:
Parent.isPrototypeOf(item), then we first check to see ifitem.__proto__ === Parent, if it is not then we check to see ifitem.__proto__.__proto__ === Parent, ... all the way until the prototype chain ends (<...>.__proto__ === null).
With this we can build a basic function to emulate this method and add in some debugging helpers to see how it works:
function isPrototypeOf(obj, parent) {
// a function to search the prototype chain of object to see if it's found in parent
let isFound = false;
let proto = obj.__proto__;
while (proto) {
console.log('Proto: ', proto);
if (proto === parent) {
console.log('Found!');
isFound = true;
break;
}
proto = proto.__proto__;
}
return isFound;
}
class SuperKlass {};
class SubKlass extends SuperKlass {};
const superKlass = new SuperKlass();
const subKlass = new SubKlass();
console.log(isPrototypeOf(SubKlass, SuperKlass));
console.log(isPrototypeOf(subKlass, SuperKlass.prototype));
console.log(isPrototypeOf(SubKlass.prototype, SuperKlass.prototype));
console.log(isPrototypeOf(SubKlass.prototype, SuperKlass.prototype.prototype)); // this shouldn't be found and will traverse until null
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | David542 |

