Typescript and the __proto__ attribute

你。 提交于 2020-02-27 06:36:08

问题


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.

Does anyone have any specifics on the performance overhead I might incur, or a solution that doesn't rely on __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__;
        }   
    }   
}

回答1:


You can use the ECMAScript 5.1 standard:

Object.getPrototypeOf(cursor)

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.

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__);
}

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



来源:https://stackoverflow.com/questions/22661133/typescript-and-the-proto-attribute

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!