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__;
}
}
}
prototype is a property of a Function object. It is the prototype of objects constructed by that function. __proto__ is an internal property of an object, pointing to its prototype. Current standards provide an equivalent Object.
The __proto__ property is a default property added to every object. This property points to the prototype of the object. The default prototype of every object is Object. prototype . Therefore, the __proto__ property of the person object points to the Object.
The __proto__ setter allows the [[Prototype]] of an object to be mutated. The value provided must be an object or null . Providing any other value will do nothing. The __proto__ property is a simple accessor property on Object.
Prototype is a creational design pattern that allows cloning objects, even complex ones, without coupling to their specific classes. All prototype classes should have a common interface that makes it possible to copy objects even if their concrete classes are unknown.
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With