本文介绍了打字稿和 __proto__ 属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,每次提到 __proto__ 时,通常都会提到 Brendan Eich 请求不要使用它.我一直在使用 Typescript 中的一些反射,将类的原型链导航到使用它提供的祖先类,并且很想注入一个包含类元数据的原型属性.

So every mention of __proto__ is usually followed by a reference to Brendan Eich's plea not to use it. I've been playing around with some reflection in Typescript, navigating the prototype chain of a class down to a provided ancestor class using it, and would love to inject a single prototype property holding class metadata.

是否有人对我可能产生的性能开销有任何具体说明,或者不依赖于 __proto__ 的解决方案?

Does anyone have any specifics on the performance overhead I might incur, or a solution that doesn't rely on __proto__?

编辑 - 用代码更新.这只是我输入的一个人为的例子,但它说明了我希望做的事情.我不太确定如何对 __proto__ 突变引起的感知放缓进行基准测试.但我还是试了一下.实例化、原型属性访问和方法调用在修改后的执行没有不同.

EDIT - Updated with code. This is just a contrived example I typed out but it illustrates what I'm hoping to do. I'm not quite sure how to benchmark the percieved slowdown caused by __proto__ mutation. But I gave it a shot anyways. Instantiation, prototype property access and method calls execute no differently given the modification.

class Base {
    public getClassName() : string {
        return this['_className'] || undefined;
    }
}

class Intermediate extends Base {
}

class Final extends Intermediate {
}

function traverseProtoChain(derivedClass, baseClass) {
    var cursor = derivedClass.prototype;
    while (cursor instanceof baseClass) {
        if (isDefined(cursor.constructor)) {
            var className = getProtoName(cursor);
            if (isValidString(className))
                cursor['_className'] = getProtoName(cursor);
        }

        if (isDefined(cursor.__proto__)) {
            cursor = cursor.__proto__;
        }
    }
}

推荐答案

您可以使用 ECMAScript 5.1 标准:

You can use the ECMAScript 5.1 standard:

Object.getPrototypeOf(cursor)

对于非常旧版本的浏览器,如果 Object.getPrototypeOf 不存在,您可以尝试回退到 __proto__,但您可以决定这些浏览器是否存在鉴于您的具体情况,这很重要.

For really quite old versions of browsers, you could attempt to fall back to __proto__ if Object.getPrototypeOf doesn't exist, but you can decide if those browsers are important given your specific context.

这里有一个例子说明了这一点.bar.prototype 不起作用,因为它是一个实例.getPrototypeOf 有效,并为您提供与不鼓励的 __proto__ 相同的答案.

Here is an example that shows this. bar.prototype doesn't work, because it is an instance. getPrototypeOf works and gives you the same answer as the discouraged __proto__.

class Foo {
    constructor(name: string) {

    }
}

class Bar extends Foo {

}

var bar = new Bar('x');

console.log(bar.prototype);
console.log(Object.getPrototypeOf(bar));
console.log(bar.__proto__);

所以你可以写取悦大家"...

So you could write the "pleases everyone"...

if (Object.getPrototypeOf) {
    console.log(Object.getPrototypeOf(bar));
} else if (bar.__proto__) {
    console.log(bar.__proto__);
}

最终曲线球... __proto__ 很可能在 ECMAScript 6 中标准化...值得牢记!

Final curve-ball... __proto__ is likely to become standardised in ECMAScript 6... worth bearing in mind!

这篇关于打字稿和 __proto__ 属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-29 23:42