Approach of new Object methods in ES5

Dmitry A. Soshnikov dmitry.soshnikov at gmail.com
Sun Apr 18 04:13:56 PDT 2010


Hello Brendan,

Saturday, April 17, 2010, 7:04:52 PM, you wrote:

> 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...

> })();


This desugared view with enclosing anonymous function means that
"getPrototype" name is available only in scope of of this function and
when this scope ends, "getPrototype" name will be GC'ed (and related
object too -- {value: ...}) and "Object.prototype" again won't have
"getPrototype" name outside, right?

(Although, it's a bit strange, as it shouldn't be GC'ed as there is
object related with this "name" object and vice-versa -- the "name" is
still bound to this object {value: ...}. But, I don't know exactly
about implementation).

I.e. we can use "obj.getPrototype() freely here..." -- only inside this
object (in this case -- inside this function)? And outside of this
object "obj.getPrototype()" can mean completely different thing -- with
"string" or "name" key, right? And if already was declared the same
"name"/"string" property, it isn't collide because our local "getPrototype"
name has other identity, yeah?

But is there much sense in providing this "getPrototype" name for
"Object.prototype" just inside our local library to make it convenient
just for ourselvels. In this case we can provide some simple function.

But the main goal is to achieve the most convenient and elegant code
reuse stylistic via placing this "getPrototype" directly into
"Object.prototype" and make it available for /all users/ outside the
library but not only for us inside the library.


> You have to keep your hands on the getPrototypeName const in order to
> use it as an identifier in obj.getPrototype(), of course.

Unclear; you mean I should first define const "getPrototype" and then
I can use it as "obj.getPrototype()"?

I.e.:

const getPrototype;
private getPrototype;

?

Or I didn't understand correctly?


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

Yes, I got it, thanks.

> 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.

As I mentioned, it seems strange, because "name" references {value: ...} object
and vice-versa {value: ...} object reference "name" object property.

It isn't relates much, but (just for example): some other languages
also allows to use not only strings as keys, but any other /hashable/
objects (using some calculated hash-value or identity for that). E.g.
in the same Python:

z = {} # it's our "Object.prototype"

def foo():

    def x():
        pass

    # use x function as a key of z dict
    z[x] = 100

foo()

# but it wasn't GC'ed and
# function-key is still in z dict
# although, we can't reference it via x key

print(z) # {<function x at 0x00BF3588>: 100}

But, I'm sure it will be implemented somehow correctly. And "name"
object will be GC'ed and after that -- {value: ...} object as there is
no references to it.

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

By the way, is there any ability to test some Harmony implementation
already? Maybe some part of it which currently is being implemented?

> 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.

Yeah, and this function from the library will detect its own
"foo.getPrototype" which it expects to detect but now our local "name"
"getPrototype" which is also available for us as "foo.getPrototype"
but with different meaning.

Thanks again,
Dmitry.



More information about the es-discuss mailing list