Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript and the __proto__ attribute

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__;
        }   
    }   
}
like image 392
Frostie Avatar asked Mar 26 '14 12:03

Frostie


People also ask

What is the difference between __ proto __ and prototype?

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.

What is __ proto __ in JavaScript?

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.

What is the use of __ proto __?

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.

What is prototyping in typescript?

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.


1 Answers

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!

like image 103
Fenton Avatar answered Sep 30 '22 18:09

Fenton