After having used my own version of an implementation of 
Function.prototype.bind for about 4 years now I recently became aware of the 
one that appears to now be standardised in ES5.

The following page suggests its definition stems from the Prototype.js library: 
<http://wiki.ecmascript.org/doku.php?id=proposals:static_generics> 

The page argues that "if we do this, we should emulate Prototype, including its 
'pre-args' feature, since it actually hacks on Function.prototype and it's a 
de-facto standard".

I have to disagree, especially with this so-called 'pre-args' feature, which 
prepends arguments to the final argument list. There are quite a few libraries 
out there, Prototype.js is only one of many, and seems to have lost 
significance over the past years. Calling it a de-facto standard and shaping 
parts of the future ECMAScript standard after it in order to remain compatible 
with it seems questionable. There are other areas were similar considerations 
seem to have played a role, the oddly named Object.keys() comes to mind.

The current implementation of bind() uses the first argument as the bind 
object, and the ones after as the arguments passed to the bound function. If 
the bound function then is called with passed arguments itself, these are 
appended to the argument list that was defined in the call of bind(). I find 
this confusing and wonder if there is any real world use for this? I have no 
experience with Prototype.js but never saw the need for such a feature. Here an 
example to illustrate the functionality of bind():

function test() {
        alert(Array.prototype.slice(arguments).join(', '));
}

test(1, 2, 3); // "1, 2, 3"

var test2 = test.bind(this, 1, 2, 3);

test2(); // "1, 2, 3"

test2(4, 5); // "1, 2, 3, 4, 5"

Am I the only one thinking it is wrong that the first and second argument to a 
function then actually end up being the 4th and the 5th when the originally 
defined function is called? If test() was defined differently and would do more 
than simply join the arguments to one string but actually used parameter names 
to perform something with them, I would find the resulting code to be pretty 
hard to read and understand.

An alternative definition could have been that the bind() call defines the 
default arguments that are passed to the bound function, which can be 
overridden when the bound function is called. The above example would end up as:

test2(4, 5); // "4, 5, 3"

This seems more logical to me, and less prone to errors.

Another issue I have with bind() is that there is no alternative version of it 
that receives an array for the arguments passed to the function, in analogy to 
the differences between apply() and call(). If I had to choose only one of 
these two, I would opt for apply(), as it offers far more flexibility. A bind() 
function defined to receive the arguments as an array would still allow things 
like the above example with very little more syntax, while offering many other 
advantages at the same time:

var test2 = test.bind(this, [ 1, 2, 3 ]);

or:

var args = [ 1, 2, 3 ];

if (passMoreArgs)
        args.push(4, 5, 6);

var test2 = test.bind(this, args);

I hope this serves as an understandable illustration.

With many of the recent additions to the language I continue to be a bit 
puzzled by the decision making process. I think things should not just be taken 
over from a library that is at one point in fashion. Functionality should be 
discussed and formulated in a way that feels true to the philosophies in the 
ECMAScript language. Such libraries are good because they point out things 
currently missing in the language. But they should be seen as starting points 
for a dialogue, not as the final word.

Jürg



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

Reply via email to