Array.forEach() et al with additional parameters

# Christian Mayer (10 years ago)

I'm just stumbling over a little improvement (syntactic sugar) that could help to make code a bit smaller (-> less to debug, read,

understand, etc. pp.)

When you want to pass additional parameters to the Array.forEach() callback function you currently must work with an additional (anonymous) function that is just wrapping stuff. (And for heavily recursive stuff cutting the useable call stack in half...)

Currently:

function myCallback( element, count, array, additionalFoo ) { console.log( 'Callback #' + count + ': ' + element, additionalFoo ); }

[1,2,3].forEach( function( element, count, array ){ myCallback( element, count, array, 'additionalFoo' ); });

New:

[1,2,3].forEach( myCallback, undefined, 'additionalFoo' );

It could be discussed whether the additions parameter is only one (and thus the programmer has to pass multiple information in a Array or Object) or if all additional parameters will be passed on to the callback function.

The same holds for the similar functions "map", "every" and "some".

What do you think?

# Gary Guo (10 years ago)

I think extending standard libraries/functions is not the most elegant approach. I think what you suggest is basically trying to bind some parameter that isn't the first few continuous parameter (in this case, it is the 4th parameter) while keeping the first few parameter unbound. I believe there should be a way created to bind any parameter we want instead of extending the standard library we have.

For example, in your case,

[1,2,3].forEach(myCallback.bindParameter(3, 'additionalFoo'))

might be a better solution, btw, use the arrow function, it can be written as

[1,2,3].forEach((element, count, array) => myCallback(element, count, array, 'additionalFoo'));

which isn't too complicated, and at least to me, it is acceptable. bindParameter function is not very hard to implement:

Function.prototype.bindParameter=function(idx, val){
    var func=this;
    return function(){
        var arg=Array.prototype.slice.call(arguments);
        arg[idx]=val;
        func.apply(this, arg);
    }
}
# David Bruant (10 years ago)

Le 20/12/2014 13:47, Gary Guo a écrit :

bindParameter function is not very hard to implement:

Function.prototype.bindParameter=function(idx, val){
    var func=this;
    return function(){
        var arg=Array.prototype.slice.call(arguments);
        arg[idx]=val;
        func.apply(this, arg);
    }
}

It's even easier if you use bind ;-)

Function.prototype.bindParameter = function(...args){ return this.bind(undefined, ...args) }

# Gary Guo (10 years ago)

On Mon, 22 Dec 2014 11:37:04 +0100, David Bruant <bruant.d at gmail.com> wrote:>Function.prototype.bindParameter = function(...args){

return this.bind(undefined, ...args) }

But this will bind all parameters. In Christian Mayer's situation, she wants first three parameters unbound while your solution will not work. :-)

# Andrea Giammarchi (10 years ago)

if you don't need a context, you can simply use it to pass anything you want.

as example, instead of this

On Sat, Dec 20, 2014 at 12:12 PM, Christian Mayer <mail at christianmayer.de>

wrote:

[1,2,3].forEach( myCallback, undefined, 'additionalFoo' );

you could do this:

[1,2,3].forEach( callback, ['additionalFoo']);

and callback will look like

function callback( element, count, array ) { myCallback.apply(nulll, element, count, array.concat(this)); }

In this way you can prepend, append, swap index, use just what you need ... etc ... I don't think it can be simplified any better with yet another change to the Array API

Best

# Andrea Giammarchi (10 years ago)

forgot squared brckets ...

myCallback.apply(nulll, [element, count, array].concat(this));

# Marius Gundersen (10 years ago)

doesn't fat-arrow solve this? It's not that verbose, and you can put the arguments in any order you want

[1,2,3].forEach(element => myCallback("something else", element));

Marius Gundersen