Concise Method Binding
Gilbert B Garza
gilbertbgarza at gmail.com
Wed Nov 11 18:00:42 UTC 2015
Forgive me if I'm missing the point, but isn't the entire purpose of using
classes to make all instances share the same function in memory via `this`
? If you want methods to always be bound, why not use closures instead?
```js
function Person (name) {
var person = this
person.greet = function () {
return person.name + " says hi!";
};
}
var alice = new Person('Alice');
alice.greet() //=> "Alice says hi!";
var f = alice.greet;
f() //=> "Alice says hi!";
```
On Wed, Nov 11, 2015 at 10:59 AM, JD Isaacks <jd at jisaacks.com> wrote:
> Ahh, good point Bergi. Thanks for brining that up.
>
> On Wed, Nov 11, 2015 at 11:55 AM, JD Isaacks <jd at jisaacks.com> wrote:
>
>> I like this very much. I would prefer this to my recommendation. So how
>> to we go about proposing it as a change to an existing proposal?
>>
>> On Wed, Nov 11, 2015 at 11:45 AM, Andrea Giammarchi <
>> andrea.giammarchi at gmail.com> wrote:
>>
>>> The way it could work is similar to the following one:
>>>
>>> ```js
>>>
>>> (function (wm){'use strict';
>>>
>>> // just to show the possible internal slot mechanism
>>> Object.prototype.boundTo = function (method) {
>>> // since I've used this for ages now in eddy.js, just replicating
>>> var fn = typeof method === 'function' ? method : this[method];
>>> var bound = wm.get(this);
>>> if (!bound) wm.set(this, bound = {fn:[], bound:[]});
>>> var i = bound.fn.indexOf(fn);
>>> if (i < 0) bound.bound[i = bound.fn.push(fn) - 1] = fn.bind(this);
>>> return bound.bound[i];
>>> };
>>>
>>> }(new WeakMap));
>>>
>>>
>>> // example
>>> var obj = {method: function () { return this; }};
>>>
>>> // now, whenever needed
>>> obj.boundTo(obj.method);
>>>
>>> // will create the slot and set it up with obj.method
>>> // so that the following is true
>>> obj.boundTo(obj.method) === obj.boundTo('method') &&
>>> obj.boundTo('method')() === obj;
>>>
>>> // if it's about another method
>>> // the equivalent of this
>>> ::obj.anotherMethod
>>>
>>> // whould be
>>> obj.boundTo(anotherMethod);
>>>
>>> ```
>>>
>>> The string fallback is not needed or relevant, it's just a semantic
>>> shortcut in my example to reach the method through the object without
>>> repeating the object name
>>>
>>> Regards
>>>
>>>
>>>
>>>
>>> On Wed, Nov 11, 2015 at 4:23 PM, JD Isaacks <jd at jisaacks.com> wrote:
>>>
>>>> Yes your point of view is more clear now, I like this is a lot.
>>>>
>>>> But I do not know how that would be transpiled or what the desugared
>>>> version would look like. However, that would be awesome as you described.
>>>>
>>>> A thing to note. You keep using `obj::method` which is different from
>>>> `::object.method` the former is when method is not already attached to the
>>>> object, the later is for then it is.
>>>>
>>>> An example:
>>>>
>>>> ```
>>>> let foo = function(){};
>>>> let bar = {};
>>>>
>>>> bar::foo // foo.bind(bar);
>>>> ```
>>>>
>>>> verses
>>>>
>>>> ```
>>>> let bar = { foo(){} };
>>>>
>>>> ::foo.bar // foo.bar.bind(foo);
>>>> ```
>>>>
>>>> I think both cases theoretically would be awesome to work as you
>>>> described. Just fuzzy on how it would look underneath.
>>>>
>>>> On Wed, Nov 11, 2015 at 11:14 AM, Andrea Giammarchi <
>>>> andrea.giammarchi at gmail.com> wrote:
>>>>
>>>>> Yeah, I've got that, my point is that whenever you need it you just
>>>>> `obj::method`
>>>>>
>>>>> Your example indeed says that currently the proposal is that
>>>>> `obj::method` is similar to `obj.method.bind(obj)` which is indeed always
>>>>> different and indeed you want something that makes method always the
>>>>> same/unique bound one, which I believe is universally the preferred way.
>>>>>
>>>>> What are two different bound of the same method useful for? Pretty
>>>>> much nothing, IMHO, while having a shortcut to lazily obtain a single bound
>>>>> version of that method for that object can be useful in many ways, as
>>>>> example `obj.on('event', anotherObj::method)` where it's always possible at
>>>>> that point to `obj.removeListener('event', anotherObj::method)` in case its
>>>>> needed.
>>>>>
>>>>> Having a shortcut that all it does is replace something already short
>>>>> to write like a `.bind` feels to me like a missed opportunity.
>>>>>
>>>>> Moreover, with this improvement you won't need/care to have self-bound
>>>>> methods at all
>>>>>
>>>>> ```js
>>>>> let obj = { method(){} };
>>>>>
>>>>> // and whenever needed you use
>>>>> obj::method;
>>>>> ```
>>>>>
>>>>> Hope my POV is more clear now.
>>>>>
>>>>> Regards
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> On Wed, Nov 11, 2015 at 4:01 PM, JD Isaacks <jd at jisaacks.com> wrote:
>>>>>
>>>>>> I think what you are suggesting already exists with `::obj.method`
>>>>>> which evaluates to `obj.method.bind(obj)`
>>>>>>
>>>>>> However, this creates a new function each time so `::obj.method
>>>>>> !== ::obj.method`, not sure how `::obj.method === ::obj.method` would work.
>>>>>>
>>>>>> I sort of agree with you that using it that way would be preferred.
>>>>>> However if the community wants bound methods attached to objects, there is
>>>>>> currently no way to do that with an object literal.
>>>>>>
>>>>>> You would have to do something like:
>>>>>>
>>>>>> ```
>>>>>> let obj = {};
>>>>>> obj.method = function(){}.bind(obj);
>>>>>> ```
>>>>>>
>>>>>> With my proposal you can.
>>>>>>
>>>>>> ```
>>>>>> let obj = { ::method(){} };
>>>>>> ```
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> On Wed, Nov 11, 2015 at 10:20 AM, Andrea Giammarchi <
>>>>>> andrea.giammarchi at gmail.com> wrote:
>>>>>>
>>>>>>> Just my thoughts, I wouldn't put any self-bound thing in the class
>>>>>>> and rather improve that `::` proposal so that whenever you `obj::method` it
>>>>>>> creates a uniquely bound callback so that `obj::method === obj::method` and
>>>>>>> at that point whenever you need to export, pass, or use such method you
>>>>>>> just `obj::method` or `obj::method()` or `let method = obj::method` and
>>>>>>> bring the pattern whenever it's needed instead of being slightly different
>>>>>>> per each "place" (class rather than objects)
>>>>>>>
>>>>>>> That would make it lazy, usable for events (in order to be able to
>>>>>>> also remove them) and easily transpilable for smoother migration.
>>>>>>>
>>>>>>> Having `class A { ::method() {} }` feels like somebody is playing
>>>>>>> too much with the protoype or "accidentally" polluting the constructor
>>>>>>>
>>>>>>> Regards
>>>>>>>
>>>>>>>
>>>>>>> On Wed, Nov 11, 2015 at 2:50 PM, JD Isaacks <jd at jisaacks.com> wrote:
>>>>>>>
>>>>>>>> Andrea, Sort of. I am talking about adding an additional place
>>>>>>>> where that operator `::` can be used -- with concise methods.
>>>>>>>>
>>>>>>>> Currently they cannot be used in the way I described above but I
>>>>>>>> think there are several reasons why it makes sense.
>>>>>>>>
>>>>>>>> _______________________________________________
>>>>>>>> es-discuss mailing list
>>>>>>>> es-discuss at mozilla.org
>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151111/b78f2593/attachment-0001.html>
More information about the es-discuss
mailing list