Object.getPrototypeOf无法__proto__无法对象.constructor.prototype填充

时间:2013-05-29 23:17:20

标签: javascript inheritance constructor prototype es5-shim

我一直在浏览一些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__不存在的环境中,有没有办法实现上述代码?

我的感觉是没有,但我只是想检查一下我没有遇到过的一些信息。

1 个答案:

答案 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 v​​25,FireFox v20和Opera 12.14上测试过:它们都是我提供的)

相关问题