Re: addEvent - The late entry :)



jdalton wrote:
@Richard Cornford
Indeed so far so that their only way out is to petition for a
new - bind - method in the new language versions so that faster
native code can rescue their authors from the consequences of
original designs.

As far as I know the Prototype core members have not petition
for a native bind method.

Maybe, but that has not stopped the authors of other similar libraries making such petitions, and citing Prototype.js methods in order to bolster their position.

I believe other developers have seen its worth and have
requested its addition.

I dislike the tone of your comment.

Should I take it that the contempt is coming across?

The authors are perfectly
capable and do not need “rescuing”.

The evidence (past and present) suggests otherwise.

You make some very good points about Prototype’s bind method.

You don't say?

There are been some performance patches submitted that deal
with bind and other methods:
http://prototype.lighthouseapp.com/attachments/31739/0467-Optimize-bind-bindAsEventListener.patch
<snip>

That ends up with a method that looks like:-

| bind: function() {
| if (arguments.length < 2 && Object.isUndefined(arguments[0]))
| return this;
| var __method = this, args = $A(arguments), object = args.shift();
| if (args.length) {
| return function() {
| return __method.apply(object, args.concat($A(arguments)));
| }
| }
| return function() {
| return __method.apply(object, arguments);
| }
| },

- which is a bit of a half-arse effort at improving performance, and faulty in terms of the logic it uses. The branch that just returns this is only acted upon if the value of the first argument is undefined, but the apply and call method both use the global object as the - this - value if their first argument is null or undefined. Javascript offers a very simple test that discriminated null and undefined form all other values, so that could be used in place of the comparatively heavyweight and insufficient - Object.isUndefined(arguments[0]) - test.

As the - args - array is only to be used when it has a non-zero length it would be better to only create that array in the branch that uses it. It remains where it is because the - object - variable needs to be initialised for both of the following branches. Except in reality it does not need to be initialised at all. If instead of using a variable, - object - had been declared as a single formal parameter for the method that parameter would have automatically been assigned the same value a arguments[0]. Having done that the - args - array creation can be moved into the branch that uses it, and so not executed at all when only one argument was used with the - bind - method.

Once the - object - parameter is being used it is no longer necessary to - shift - its value out of the front of the array, and that opens up the possibility of using an alternative approach to create the array. Specifically applying the - Array.prototype.slice - to the arguments object, as in - args = Array.prototype.slice.call(arguments, 1); -, where fast native code creates the desired array and skips the first argument in the process.

And finally, using the - concat - method to append an array created from the arguments object is very convoluted and relatively inefficient when the arguments object can be used as the second argument to the - apply - method and the - apply - method could be called on - push -, which will take any number of arguments and append them to an array. That is:- __method.apply(object, args.concat($A(arguments))); - can be replaced with - __method.apply(obj, args.push.apply(args, arguments)); - and should result in superior performance.

The result might resemble:-

Function.prototype.bind = function(obj){
var args, fnc;
if(arguments.length > 1){
fnc = this;
args = Array.prototype.slice.call(arguments, 1);
return (function(){
return fnc.apply(obj, args.push.apply(args, arguments));
});
}else if(obj == null){
return this;
}else{
fnc = this;
return (function(){
return fnc.apply(obj, arguments);
});
}
};

- which has actually become very different form the authors of Prototype.js's best efforts to date. And it has lost all of its internal dependencies on Prototype.js in the process. (Maybe there is a lesson in that.)

Your faith in the authors or Prototype.js is touching, but no justification for it is evident in the code they write. An I bet that when they become aware of some of the possibilities suggested above they will happily take all the credit for any resulting performance gains that would be the consequences of their applying them (and some can be applied all over the place in Prototype.js methods).

Richard.

.



Relevant Pages

  • Re: ASP.NET Remoting problem
    ... > I have added a web reference to this service. ... > But now I cannot bind an array of this object to a DataGrid because ... > properties to be able to bind with data grid. ...
    (microsoft.public.dotnet.framework.aspnet)
  • Re: ASP.NET Remoting problem
    ... > I have added a web reference to this service. ... > But now I cannot bind an array of this object to a DataGrid because ... > properties to be able to bind with data grid. ...
    (microsoft.public.dotnet.framework.aspnet)
  • Re: Binding an array to a Datagrid
    ... It was bound to a Dataset but some of the columns were missing, I assumed I would have more control using an array ... > and then passing that array to a DataGrid. ... return a DataTable from Sql Server and bind directly to that. ...
    (microsoft.public.dotnet.languages.csharp)
  • RE: Binding an ArrayList of custom objects to a dropdownlist
    ... Expose the member variables of the object that you would like to bind to the combobox as properties. ... > Let's say I have an array of custom 'Person' objects. ...
    (microsoft.public.dotnet.framework)
  • Re: Filling a ComBox manually with DisplayMember and ValueMember
    ... static, then bind to it. ... > give a DataView or a DataTable to Combo's DataSource property. ... > need to fill a combo quickly with 2 or 3 static items. ... > Is there any way to do that through Array ou String and have Display/Value ...
    (microsoft.public.dotnet.framework.adonet)