From: Dmitry A. Soshnikov on
On 14.06.2010 15:38, Richard Cornford wrote:
> On Jun 14, 11:46 am, Dmitry A. Soshnikov wrote:
>> On 13.06.2010 23:50, Asen Bozhilov wrote:
> <snip>
>>> | Function.prototype.bind (thisArg [, arg1 [, arg2, ...]])
>>> | 15.3.4.5
>>> | 4. Let F be a new native ECMAScript object .
>>
>>> That step is described by ECMA-262-5 without any conditions.
>>> And the following behavior is conformance:
>>
>>> function F(){}
>>> var thisValue = {};
>>> print(F.bind(thisValue) !== F.bind(thisValue)); //true
>>
>>> I do not see any purposes for that design. The design of `bind'
>>> permit memory optimizations but unfortunately ECMA-262-5 does
>>> not describe that.
>>
>> Yep, they could mention this optimization. If the function is
>> the same (with the same lexical environment chain), then, if
>> there are no pre-bound partial args, the bound functions should
>> not be different.
> <snip>
>
> Remember that javascript's functions (including functions returned
> from calls to - bind -) are objects and so may, at any future time,
> have properties added and values assigned to those properties.
>
> var a = F.bind(thisValue);
> var b = F.bind(thisValue);
>
> a.something = 'test';
>

Yeah, really, somehow I completely forgot about it when was replying to
Asen's question -- although, myself, mentioned in the article (with
example creating `prototype' property) that function objects created via
`bind' method are extensible.

> Do you now expect - b - to have a property called 'something' and for
> that property to have the value 'test'? And worse, would you want the
> existence of - b.something - to depend on an optional optimisation
> where it may be there in some environments and not there in others? As
> things stand, ES5 guarantees that each function returned from a call
> to - bind - has unique identity, and so that an implementation behave
> as if it has unique identity. I think that this is a good thing.
>

Yes, of course. Such optimization leads to ambiguities. So the ES5 is
logical and correct in this question.

Dmitry.

From: Dmitry A. Soshnikov on
On 14.06.2010 17:46, Asen Bozhilov wrote:
> Richard Cornford wrote:
>
>> Remember that javascript's functions (including functions returned
>> from calls to - bind -) are objects and so may, at any future time,
>> have properties added and values assigned to those properties.
>> var a = F.bind(thisValue);
>> var b = F.bind(thisValue);
>>
>> a.something = 'test';
>
> It can depend on setter/getter and it is not necessary the assigned
> value to be accessed by:
>
> b.something;
>

If it will be the same object (with the same identity), how will you
distinguish that getting from "some" object should return this property
and from "other" not? I put "some" and "other" in quotes, because there
is only one the same object. It could be some virtual table of
properties, related with index, but, that to complex implementation and
not worth all that.


>> Do you now expect - b - to have a property called 'something' and for
>> that property to have the value 'test'? And worse, would you want the
>> existence of - b.something - to depend on an optional optimisation
>> where it may be there in some environments and not there in others? As
>> things stand, ES5 guarantees that each function returned from a call
>> to - bind - has unique identity, and so that an implementation behave
>> as if it has unique identity. I think that this is a good thing.
>
> Certainly true, but in the near future we will see the approaches
> like:
>
> for (var i = 0, len = coll.length; i< len; i++) {
> coll[i].onclick = function () {
> //....
> }.bind(thisValue);
> }
>
> And by ECMA-262 should be created `len' * 2 objects. Would you want
> implementations to follow that or they will make optimizations behind
> the scene and behind the ECMA-262 standard?
>

By the way, I see that "joined objects" are gone from the ES5 too.

Dmitry.
From: Richard Cornford on
On Jun 14, 2:46 pm, Asen Bozhilov wrote:
> Richard Cornford wrote:
>> Remember that javascript's functions (including functions
>> returned from calls to - bind -) are objects and so may,
>> at any future time, have properties added and values
>> assigned to those properties.
>> var a = F.bind(thisValue);
>> var b = F.bind(thisValue);
>
>> a.something = 'test';
>
> It can depend on setter/getter and it is not necessary the
> assigned value to be accessed by:
>
> b.something;

If the whole behaves as if - a - and - b - are unique objects then how
that is a achieved doesn't matter much.

>> Do you now expect - b - to have a property called 'something'
>> and for that property to have the value 'test'? And worse, would
>> you want the existence of - b.something - to depend on an optional
>> optimisation where it may be there in some environments and not
>> there in others? As things stand, ES5 guarantees that each
>> function returned from a call to - bind - has unique identity,
>> and so that an implementation behave as if it has unique identity.
>> I think that this is a good thing.
>
> Certainly true, but in the near future we will see the approaches
> like:
>
> for (var i = 0, len = coll.length; i < len; i++) {
> coll[i].onclick = function () {
> //....
> }.bind(thisValue);
>
> }
>
> And by ECMA-262 should be created `len' * 2 objects.

There is no need to wait for the future, I have already seen code
exactly like that. Whether it should be seen is another matter given
that, as it stands, this:-

var f = (function () {
//....
}).bind(thisValue);

for (var i = 0, len = coll.length; i < len; i++) {
coll[i].onclick = f;
}

- should do the same with the creation of only two function objects.

> Would you want implementations to follow that or they will make
> optimizations behind the scene and behind the ECMA-262 standard?

Optimisations behind the scenes are never unwelcome, so long as the
specified behaviour is achieved. Here the functions returned from
calls to - bind - must behave as if they each have unique identify.

Richard.
From: Richard Cornford on
On Jun 14, 3:03 pm, Dmitry A. Soshnikov wrote:
> On 14.06.2010 17:46, Asen Bozhilov wrote:
<snip>
>> ... . Would you want implementations to follow that or they will
>> make optimizations behind the scene and behind the ECMA-262
>> standard?
>
> By the way, I see that "joined objects" are gone from the ES5 too.

Some years ago some of the participants in this group put quite a lot
of effort into trying to find evidence for "joined objects" in
javascript implementations, with zero success. So probably the only
thing that is lost by their being removed from ES5 is the possibility.

Richard.
From: Garrett Smith on
On 6/14/2010 8:19 AM, Richard Cornford wrote:
> On Jun 14, 2:46 pm, Asen Bozhilov wrote:
>> Richard Cornford wrote:
>>> Remember that javascript's functions (including functions

[...]

>> Certainly true, but in the near future we will see the approaches
>> like:
>>
>> for (var i = 0, len = coll.length; i< len; i++) {
>> coll[i].onclick = function () {
>> //....
>> }.bind(thisValue);
>>
>> }
>>
>> And by ECMA-262 should be created `len' * 2 objects.
>
> There is no need to wait for the future, I have already seen code
> exactly like that.

I see it too.

I remember seeing that approach being used in Google Gears code, with
code comments labeled "aa" (apparently the code reviewer).

The approach given is inefficient and clumsy. Beginners want to do this
to fix variable this arg but it's not necessary.

A better solution for what the above code appears to be doing would be
to register an event handler -- just one -- on a common ancestor and use
delegation.

// Typical approach using delegation.
container.onclick = function(ev) {
var target = getTarget(ev);
if(isPanelActuator(target)) {
panelActuatorClickHandler(target, ev);
}
}

The initialization is reduced to one assignment and one event handler
function object creation. There is no need for a bind function. Although
the approach uses a layer indirection with bubbling, the resulting code
is actually shorter and simpler.

Garrett