On Apr 2, 2012, at 4:22 PM, Jorge wrote:

> On Apr 2, 2012, at 9:47 PM, Brendan Eich wrote:
>> Douglas Crockford wrote:
>>> 
>>> 
>>> It seems I misunderstood what we were agreeing to. I think the (this...) 
>>> form is critically important, and the immutability thing as well.
>> 
>> (...)
>> 
>> I agree that leading |this| could be important for dynamic non-method 
>> use-cases, but those are relatively rare (let's not discount JQuery, but 
>> again, it could use long functions and survive). We could put 
>> leading-this-parameterization on the agenda for May, but we'll have to be 
>> careful not to lose consensus on arrows.
> 
> I was chatting this evening with a friend about this (ruby) thing:
> 
> class Numeric
>  (Math.methods - Module.methods - ["hypot", "ldexp"]).each do |method|
>    define_method method do
>      Math.send method, self
>    end
>  end
> end
> 
> 
> And I showed him how one could do that easily in JavaScript:
> 
> Object.getOwnPropertyNames(Math).forEach(function (key) {
>  if (typeof Math[key] === 'function') {
>    Number.prototype[key]= function () {
>      return Math[key](this);
>    };
>  }
> });
> 
> 

Of course this is a very specialized transfer in that you need to remap 
functions (that don't reference this) into a method that does.  Essentially you 
are creating a wrapper method that calling a function passing the method's this 
value as an argument to the function all.  This isn't like a normal object 
composition (eg "Object.extend" ) where you are just method references from one 
object to another. In this case you have to know how to make each function.  
You can do this because you know that every function valued property follow the 
same form and can use the same mapping pattern.  i suspect that this is not a 
very common situations.  Normally the methods you are transferring probably 
won't be this regular. or will have other issues (such a super reference) that 
would probably require you to use slightly different techniques such as 
Object.defineMethod.

Object.getOwnPropertyNames(Math).forEach(function (key) {
 if (typeof Math[key] === 'function') {
   Object.defineMethod(Number.prototype,key,function () {
     return Math[key](this);
   });
 }
});

Bottom line, I'm not use that this really represents a very common scenario...

> Then I thought, let's see how would that look like with arrows ?

But that would be wrong assume that arrows always lexically bind this.  

> 
> 
> Object.getOwnPropertyNames(Math).forEach((key) => {
>  if (typeof Math[key] === 'function') Number.prototype[key]= () => 
> Math[key](this);
> });
> 

To define a method you really need to use either a function definition (as in 
your original snippet) or alternatively a concise method in an object literal:

Object.getOwnPropertyNames(Math).forEach((key) => {
 if (typeof Math[key] === 'function') Number.prototype[key]= {m() {return 
Math[key](this)}.m;
});

This suggests that we might benefit from defining Object.defineMethod in a way 
that leverages concise method syntax:

Object.getOwnPropertyNames(Math).forEach((key) => {
 if (typeof Math[key] === 'function') Object.defineMethod(Number.prototype,key, 
{method() {return Math[key](this)});
   //if method arg is a non-functjon object use the value of its property named 
'method'
});


> And it turns out that here, the outer/enclosing context `this` isn't the one 
> you want/need. You'd need a dynamically bound `this` instead:

yes, but the root problem is trying use an arrow functions to define a method.  
Based upon these examples I'm inclined to think that Object.defineMethod should 
throw if the value it needs to install is a arrow function value.

> 
> Object.getOwnPropertyNames(Math).forEach((key) => {
>  if (typeof Math[key] === 'function') Number.prototype[key]= (this) => 
> Math[key](this);
> });
> 
> and thus the this-in-the-parameters-list trick.
> 
> I don't think it's such a rare case: Inside a constructor function called 
> with `new`, yes, `this` is most likely going to be the right `this` always, 
> but when you are building objects with a factory (e.g. with a .create() 
> method), the enclosing `this` usually isn't going to be the right one.

When you are building objects with a factory as you are describing you are 
presumably taking methods that were defined using an object literal or some 
other property method definition pattern:

let obj = mayFactory (arg) {
  return Object.extend({x:arg}, {
      method1() {...this...},
      method2() {...this...},
      ... /etc,
    });
};

The second argument to Object.extend might have been define remote but is 
likely still to be a template object with property dynamic this bound methods.  
I think the sort of this to argument remapping you show is actually pretty 
unusual. 

Allen







> -- 
> Jorge.
> _______________________________________________
> es-discuss mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/es-discuss
> 

_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to