我一直在浏览一些shim / polyfill库,看看其中一些库有Object.getPrototypeOf
的垫片。如果不存在则会使用__proto__
,如果不存在,则转为使用object.constructor.prototype
。
我理解__proto__
是“非标准”,虽然与Object.getPrototypeOf
方法略有不同,但它们可以互换。
我也理解原则上外部可访问的object.constructor.prototype
在其他两个都不存在的情况下就足够了(假设原型没有被重新分配)。
我遇到问题的地方是以下示例:
function findPropertyOwner(object, property) {
var count = 0;
do {
if (object.hasOwnProperty(property)) {
return [object, count];
}
object = Object.getPrototypeOf(object);
count += 1;
} while (object);
return undefined;
}
或者
function instanceOf(object, constructor) {
while (object) {
if (object === constructor.prototype) {
return true;
}
object = Object.getPrototypeOf(object);
}
return false;
}
通过上面的例子,我们可以说“走链子”,如果垫片回到object.constructor.prototype
,那么我们现在最终陷入无限循环的可怕境地。
我的问题:在Object.getPrototypeOf
和__proto__
不存在的环境中,有没有办法实现上述代码?
我的感觉是没有,但我只是想检查一下我没有遇到过的一些信息。
答案 0 :(得分:0)
基于@squint的评论,我将介绍我尝试过的解决方案。根据{{3}},我根据Object.getPrototypeOf
重新编写了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;
};
}
}
的一般垫片,这些垫片似乎很常见。
跨浏览器实施
现在显而易见的问题是:我们如何开始使用 Object.getPrototypeOf今天如果大多数浏览器没有实现它 然而?与此同时,我们可以使用类似下面的代码 某种形式的兼容性:
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; }; } }
虽然它不是100%现货(因为.constructor属性是 在任何物体上都是可变的 - 完全有可能它已经存在 在某些时候由用户操纵)上面的代码应该用作 一个“足够好”的解决方案,让你度过难关,直到浏览器有好处 ECMAScript 3.1兼容性。
这就是我想出来的
new TypeError() instanceof Error; // --> true
正如我在评论中提到的,这解决了我在John Resig版本中遇到的循环原型链问题。
我确实遇到的问题(如果构造函数被篡改可能会破坏)是在我的测试中我发现我在一个特定的测试中得到了错误的结果(可能会有更多,但不是我还没找到)。测试涉及a blog by John Resig
<强>的instanceof 强>
instanceOf(new TypeError(), Error); // --> true
函数instanceOf与ES5 Object.getPrototypeOf或_ proto _
instanceOf(new TypeError(), Error); // --> false
函数instanceOf with object.constructor.prototype fallthrough
{{1}}
我所有的其他测试都给了我匹配的结果,但正如我所说,可能会有更多的不一致(构造函数没有被篡改)。这是我设法提出的最好的,但至少我不再有类似于我的问题中给出的函数的无限循环的可能性。
这是展示问题的Error objects。 (在Chromium v25,FireFox v20和Opera 12.14上测试过:它们都是我提供的)