How to use a named function for each and that

I found that using anonymous functions makes my code more readable and self-documenting, smoothing the code to more understandable stand-alone functions. Therefore, I would like to deduce the following construction from:

function Save() { myVal = 3.14 // some arbitrary value $('#myID').each(function(index,element) { if ($(this).val() === myVal) {} }); } 

IN:

 function Save() { myVal = 3.14 // some arbitrary value $('#myID').each(myFunction); } function myFunction(index,element) { if ($(this).val() === myVal) {} } 

The problem with using .bind here is that you lose the value of $ (this) inside each method, so (I don't think) I can bind myVal to myFunction.

Perhaps I could use element instead of this ?

Edit 1: I should have used .myClass instead of #myID for the example selector.

Edit 2: I do not use bind in the proposed solution because I do not think bind will work.

Edit 3: I appreciate everyone saying that the first example is more readable. I just learn the language and try different thoughts.

+4
source share
3 answers

What about:

 function Save() { myVal = 3.14 // some arbitrary value $('#myID').each(myFunction(myVal)); } function myFunction(myVal) { return function(index, element) { if ($(this).val() === myVal) {} } } 
+4
source

You do not lose access to this ; you lose access to myVal because myVal not known inside myFunction , mainly because this function is defined in an area that does not have a definition for myVal .

What you can do is something like this:

 function myFunction(index, element, myVal) { if ($(this).val() === myVal) {} } 

and then:

 function Save() { myVal = 3.14 // some arbitrary value $('#myID').each(function(index, element) { myFunction.call(this, index, element, myVal); }); } 

That way, if you have a lot of logic inside myFunction , you can still separate it and just call myFunction from the .each) callback. Not that myFunction is called using .call , because that way you can pass an explicit value to this (first argument). Therefore, this is the same this that is inside the .each .

To be honest, the first option is much more readable, and you really do not get much by dividing the code this way.

+2
source

this in this context will be the same. The only thing you lose is myVal . You are right that you cannot use Function.bind , because it does not allow you to specify in order to preserve the original (call time) this

Here you can pass myVal and keep the same this using a modified version of Function.bind that we call myBind

 /** * Binds the given function to the given context and arguments. * * @param {function} fun The function to be bound * @param {object} context What to use as `this`, defaults * to the call time `this` * @param {object[]} customArgs Custom args to be inserted into the call * @param {number} index Where to insert the arguments in relationship * to the call time arguments, negative numbers count from the end. That is, -1 to insert at the end. Defaults to a 0 (beginning of list). * */ function myBind(fun, context, customArgs, index) { return function() { // Default the index index = index || 0; // Create the arguments to be passed, using an old trick // to make arguments be a real array var newArgs = Array.prototype.slice.call(arguments, 0); // Tack the customArgs to the call time args where the user requested var spliceArgs = [index, 0].concat(customArgs); newArgs.splice.apply(newArgs, spliceArgs); // Finally, make that call return fun.apply(context || this, newArgs); } } function Save() { myVal = 3.14 // some arbitrary value $('#myID').each( // myFunction wil be called with myVal as its last parameter myBind(myFunction, null, [myVal], -1) ); } function myFunction(index, element, myVal) { if ($(this).val() === myVal) { // do it here } } 

To demonstrate the flexibility of this function, let us associate more than one argument and you need to insert it at the beginning of the call time arguments

 function Save() { var myVal = 3.14, val2 = 6.28; // some arbitrary values $('#myID').each( // myFunction wil be called with myVal and val2 as its first parameter myBind(myFunction, null, [myVal, val2], 0); ); } // Since I don't need element, it already available as this, we don't // declare the element parameter here function myFunction(myVal, val2, index) { if ($(this).val() === myVal || $(this.val() === val2)) { // do it here } } 

This is almost the same answer as Samuel Kayieri. The only difference is that we are creating another version of Function.bind that does not bind this , just the arguments. Another advantage of this version is that you can choose where to insert related arguments,

+2
source

All Articles