On Oct 1, 2011, at 11:11 AM, François REMY wrote:

> My code was not a fix, it was intended to show that while your first case’ 
> behavior was explained in the spec (super had to be null), the one of my own 
> case was not (ie: the interaction of ‘super’ with bind).

All well defined in the proposal

Remember the |super| can be thought of as having two values depending upon the 
usage.  When evaluated for value, it value is always the same as the this 
value.  In a bound function the, evaluated value of super is the bound this 
value.  The other value of super is the property lookup continuation value.  
That value is statically bound when the function is created  (ie, installed as 
a method in an object). It is the value of the object's  [[Prototype]] internal 
property.

var widget = {
    hookup: function() {
        // |this| is widget  >>>>>> actually depend upon how function is 
invoked, normal yes normally widget
        // |super| is widget  >>>>>>  no, and not null.  For evaluation 
purposes it is the same as |this|
                                          >>>>>>  the lookup continuation is 
Object.prototype which is the [[Prototype]] of the containing obj lit
        window.addEventListener('load', function(event) {
            // |this| is widget
            // |super| ??   >>>>>>  for evaluation purposes it is widget (as 
bound by bind) >>>
                                    >>>>>> the lookup continuation is null, 
because it doesn't meet the "part of an object literal" criterial below :
from proposal: "When a function that references super is defined as part of an 
object literal its [[Super]] internal property is set to the same value as the 
[Prototype]] internal property of the object created by the object literal. 
Such functions include functions defined using method property definitions, 
functions defined using get or set definitions, and functions defined as a 
MemberExpression within the AssignmentExpression of a PropertyAssignment.  
Functions defined outside of object literals (or class declarations) that 
reference super are created with their [[Super]] internal property set to null. 
Property accesses based off of super always perform property lookups start with 
the object that is the the value of the containing function’s [[Super]] 
internal property. If [[Super]] is null, the property lookup immediately fails 
and produces the value undefined."
        }.bind(this), false);

Expressing this criteria another way, a function in an object literal only gets 
a non-null [[Super]] value if the function is either the immediate value of an 
data property or the [[Get]] or [[Set]] function of an accessor property. 


>  
> I’ve no idea of how we should solve the problem. Maybe the ‘bind’ method 
> should create a copy of the original function whose ‘boundThis’ is equal to 
> the object’s this and whose ‘super’ is equal to Object.getPrototypeOf(this).


Object.defineMethod is used to rebind [[Super]]  (actually creates a new 
function with the same code and [[Scope]] but a different [[Super]] binding).

defineMethod and bind have nothing to do with each other.  bind is about the 
value of |this| which is always the same as the value of |super|. defineMethod 
is about the the value of [[Super]] - the property lookup continuation point.




>  
> function Obj() { }
> Obj.prototype.getX = function() { return 10; }
>  
> function Obj2() { Obj(this); }
> Obj2.prototype = Object.create(Obj.prototype);
> Obj2.prototype.getX = function() { return super.getX()+1; }
[[Super]] of getX would be null. You probably want to say:
      Object.defineMethod( Obj2.prototype, 'getX', function () {return 
super.getX() + 1};
in which case [[Super]] of getX would be Obj.prototype
>  
> var a = new Obj2();
> var b = Object.create({getX:function() { return 100; }});
> b.getX=a.getX.bind(b);
I suspect what you really want to say above is
                Object.defineMethod(b, 'getX', a.getX).bind(b);
>  
> assert(a.getX() == 11);
yes 11 is correct
> assert(a.getX() == 101); // or should it be 11?
false.  Or did you mean
    assert (b.getX() == 101)

as written above, g.getX) will also be 11.  this is because of the static 
binding of [[Super]] when the method is installed



> A typical programming language would (probably) require 11,
I know of no other programming language that permits something like bind to 
permanently fix a methods this bind or that permits a method (that references 
this) to be invoked without supply explicitly supplying a this value. 


> but then you’ve no way to solve the asynchronous pattern (super would remain 
> null and only this would be bound).

This whole business of trying to bind this in a callback is a idiom that I 
think is unique to JS.  In any other language, the problem would  solved by 
using a lambda to capture whatever state the callback function need to 
reference:

    ...
    { //lexical block
        let  actualWidget = this;
        window.addEventListener('load', function (event) {
              actualWidget.whatever();  //instead of this.whatEver
       }, false);
    };
   ...

binding this for non-method function invocations should be considered a JS 
antipattern.

Allen
        



>  
> François
>  
> From: John J Barton
> Sent: Saturday, October 01, 2011 6:16 PM
> To: François REMY
> Cc: Brendan Eich ; Axel Rauschmayer ; es-discuss
> Subject: Re: Super-calls
> 
> 
> On Sat, Oct 1, 2011 at 9:05 AM, François REMY <fremycompany_...@yahoo.fr> 
> wrote:
> In my understanding, super would be null.
>  
> What would be more complex is :
> var widget = {
>     hookup: function() {
>         // |this| is widget
>         // |super| is widget
>         window.addEventListener('load', function(event) {
>             // |this| is widget
>             // |super| ??
>         }.bind(this), false);
> Unfortunately my example and your fix are both impractical. We have to bind 
> the function *and* save a reference to it because we don't have garbage 
> collection. That provides another example to try to understand super:
>             this.loadHandler = function(event){
>                // this is widget
>                // Now super?
>                }.bind(this); 
>             window.addEventListener('load', this.loadHandler, false);
>     }
> };
> widget.hookup();
> jjb
> _______________________________________________
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to