Approach of new Object methods in ES5

Brendan Eich brendan at mozilla.com
Sat Apr 17 08:04:52 PDT 2010


On Apr 17, 2010, at 7:25 AM, Dmitry Soshnikov wrote:

> Excuse me, seems I missed something. I thought first that you  
> mentioned them in "private" viewpoint, but in this sentence you say  
> that "names" will help to place standard methods/properties in built- 
> ins prototypes avoiding naming collisions. But how will it look? Can  
> you show an example, it is very interesting.

(function () {
   private getPrototypeName;
   Object.defineProperty(Object.prototype, getPrototypeName,
     {value: function () { return Object.getPrototypeOf(this); }});

   // Your code using obj.getPrototype() freely here...

})();

You have to keep your hands on the getPrototypeName const in order to  
use it as an identifier in obj.getPrototype(), of course. Thus the  
module pattern to scope the private name. Publishing that name in a  
global variable risks collisions too, but it's another possibility and  
less likely to collide or break for-in enumeration than decorating  
Object.prototype with a string-named property.

In short, the advantage is that you can use Prototype.js-style  
instance methods, even on any object via Object.prototype delegation,  
and not ES5-style static methods, while not not polluting  
Object.prototype with string-named properties that could break some  
other script.


> If you e.g. place "getPrototype" "name" into "Object.prototype" how  
> will it help to avoid collisions if user will place "string  
> property" "getPrototype" into the "Object.prototype" (or just in  
> global object)? How will it help for "object detection"?

Note that there is no need to detect your privately-named  
getPrototype. You just define it and use it. Again the aim is to avoid  
breaking old code that tests for some other, possibly unrelated  
getPrototype on any object that delegates to Object.prototype,  
including the global object:

// This still works even in light of the above...
if (! this.getPrototype)
   this.getPrototype = function () { return this.__proto__; }

Dave just pointed out that once the module pattern scope ends, the  
privately-named Object.prototype.getPrototype is liable to be garbage  
collected since it can't be referenced or enumerated.

So the module pattern (or real modules or lexical scope, also coming  
in Harmony in some form) is as important as the Names proposal.

But scope isolation is not enough, since we are mutating a shared  
object, Object.prototype, and the heap is not scoped. Suppose you  
wanted to call a function from within your module that has monkey- 
patched Object.prototype.getPrototype, and that function is in an  
existing library that detects foo.getPrototype on some object foo.

/be


More information about the es-discuss mailing list