问题描述
因此,每次提到 __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__ 属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!