Look Ma, no "this" (was: ECMAScript Harmony)

Kris Zyp kris at sitepen.com
Sun Aug 24 17:10:30 PDT 2008


>> I don't see why it is better to have classes be sugar for closured object
>> literals rather than prototype based structures. It seems the benefits 
>> that
>> are being sought after are auto-binding on method extraction and private
>> method creation.
>
> I'm not sure what you mean by "private method creation", so I'm not
> sure whether you've covered the other main motivation: encapsulated
> instance variables.

I did not, good to know that that is the motivation.

> ES3 has only one encapsulation mechanism: lexical
> capture by closures. ES4 achieved class-private instance variables by
> use of namespaces. My earlier Classes-as-Sugar proposal suggested
> using the prototype chain much as you do here, and adding another
> property attribute to mark a property as "private". This gives
> instance-private rather than class-private variables, which is the
> safer default for a dynamic language. The new objects-as-closure sugar
> also gives instance-private encapsulation, and without proposing any
> new semantic state. I think it is better in all ways.

I am curious how you make that judgement. Creating classes using a structure 
that is fundamentally different than how inheritance/"classes" are 
predominantly done on the web today seems like an enormous drawback, and I 
don't see how avoiding the addition of a new semantic state is so valuable 
as to overcome this drawback. What is so dreadful about adding a "private" 
attribute that necessitates these class semantics based on different 
inheritance techniques? If the only barrier is for someone to do a 
desugaring exercise with the prototype based construction using existing 
semantics, I believe it is still possible to emulate private instance 
variables with prototypes (although much more awkward than with a "private" 
attribute). I could demonstrate if desired.

>> Both of these can be attained with prototype-based class
>> desugaring. If you really you want auto-binding on method extraction 
>> (which
>> IMO is of very minimal value), why not do it this way and keep class
>> semantics much closer to the prototype techniques used in JavaScript 
>> today:
>>
>> (function(){
>>   // desugared Point class
>>   Point = function(){};
>>   function privateMethod(){
>>   }
>
> I don't understand the point you're making with privateMethod. How do
> you provide encapsulated per-instance state?
>
>
>
>> However, I would prefer |this| instanceof checking instead auto-binding 
>> on
>> extraction. Rather than binding on extraction, class methods would always
>> have an implicit check to make sure they were called with an object that 
>> was
>> an instance of (instanceof) the class:
>
> In the absence of inheritance, I suppose this is safe. But it is not
> safe when combined with inheritance. If b is an instance of B which
> extends A, and B overrides A.foo(), then the author of B should be
> able to assume that no one outside b can call A.foo() on b. Your
> proposal would still allow an attacker to A.foo.call(b), which might
> violate b's integrity.

It is only an integrity violation if you assume that the author of B assumes 
that no one will call A.foo() on b. If there is no guarantees of preventing 
the A.foo() call, than the author of B just can't make any such reliances on 
such a mechanism. Alternately, if people really felt that preventing A.foo() 
calls was so important (I don't), you could use a stricter type checking 
mechanism that ensured that the method being called was the unshadowed 
method in the prototype chain.

>> By using type checking instead of binding on extraction, this would allow
>> functions that recieve a function/method as parameter to apply the 
>> function
>> to appropriate compatible object instance with apply or call:
>> function showCoordinateOnSelect(coordinateGetter){
>>   table.onclick = function(event){
>>       var point = getPointForClick(event);
>>       alert(coordinateGetter.call(point));
>>   }
>> }
>> ...
>> showCoordinateOnSelect(Point.prototype.getX);
>
> Just use a normal function instead of a method.

I am not sure I understand, are you suggesting that programmers should not 
be able to pass around a method?

Thanks,
Kris 



More information about the Es-discuss mailing list