Based on the comments by @squint I will present the solution that I tried. I reworked the general shim for Object.getPrototypeOf
that seems to be common among the libraries, based on a blog by John Resig as far as I can tell.
Cross-Browser Implementation
The obvious question now becomes: How do we begin using Object.getPrototypeOf today if most browsers don’t have it implemented yet? In the meantime we can use something like the following code for some form of compatibility:
if (typeof Object.getPrototypeOf !== "function") { if (typeof "test".__proto__ === "object") { Object.getPrototypeOf = function (object) { return object.__proto__; }; } else { Object.getPrototypeOf = function (object) { // May break if the constructor has been tampered with return object.constructor.prototype; }; } }
While it’s not 100% spot-on (since the .constructor property is mutable on any object – it’s fully possible that it could’ve been manipulated by the user at some point) the above code should serve as a “good enough” solution to tide you over until browsers have good ECMAScript 3.1 compatibility.
And this is what I came up with
if (typeof Object.getPrototypeOf !== "function") {
if (Object.prototype.__proto__ === null) {
Object.getPrototypeOf = function getPrototypeOf(object) {
return object[proto];
};
} else {
Object.getPrototypeOf = function getPrototypeOf(object) {
if (object === Object.prototype) {
return null;
}
if (object === object.constructor.prototype) {
return Object.prototype;
}
return object.constructor.prototype;
};
}
}
As I mentioned in my comments, this solves the circular prototype chain problem that I experienced with the John Resig version.
The problem that I do have with it (other than it may break if the constructor has been tampered with) is that during my tests I found that I get false result on one particular test (there may be more, but not that I have yet found). The test/s concern the Error objects
instanceof
new TypeError() instanceof Error; // --> true
function instanceOf with ES5 Object.getPrototypeOf or _proto_
instanceOf(new TypeError(), Error); // --> true
function instanceOf with object.constructor.prototype fallthrough
instanceOf(new TypeError(), Error); // --> false
All my other testing gave me matching results, but as I said, there may be more inconsistencies out there (where the constructor has not been tampered with). This is the best that I have managed to come up with, but at least I no longer have the possibility of infinite loops on functions similar to those given in my question.
Here is a jsfiddle that demonstrates the problem. (tested on Chromium v25, FireFox v20 and Opera 12.14: they are all that I have available)