I have found that not using anonymous functions has made my code more readable and self-documenting by flattening the code into more understandable, standalone functions. So I'd like to break out the following construct from:
function Save() {
myVal = 3.14 // some arbitrary value
$('#myID').each(function(index,element) {
if ($(this).val() === myVal) {}
});
}
Into:
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 the each method, so (I don't think) I can bind myVal to myFunction.
Maybe I could use element
instead of this
?
Edit 1: I should have used .myClass instead of #myID for an example selector.
Edit 2: I'm not using bind in the proposed solution because I don't think bind would work.
Edit 3: I appreciate everyone saying that the first example is more readable. I'm just exploring the language and trying out different thoughts.
I have found that not using anonymous functions has made my code more readable and self-documenting by flattening the code into more understandable, standalone functions. So I'd like to break out the following construct from:
function Save() {
myVal = 3.14 // some arbitrary value
$('#myID').each(function(index,element) {
if ($(this).val() === myVal) {}
});
}
Into:
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 the each method, so (I don't think) I can bind myVal to myFunction.
Maybe I could use element
instead of this
?
Edit 1: I should have used .myClass instead of #myID for an example selector.
Edit 2: I'm not using bind in the proposed solution because I don't think bind would work.
Edit 3: I appreciate everyone saying that the first example is more readable. I'm just exploring the language and trying out different thoughts.
Share Improve this question edited Apr 9, 2013 at 15:29 Phillip Senn asked Apr 9, 2013 at 15:23 Phillip SennPhillip Senn 47.7k91 gold badges261 silver badges378 bronze badges 15-
4
this
would be the same in both codes, here. – Denys Séguret Commented Apr 9, 2013 at 15:24 -
5
you do not lose the value of
this
.. you lose access to themyVal
variable.. – Gabriele Petrioli Commented Apr 9, 2013 at 15:25 -
4
$('#myID').each
is very suspect : do you have more than one element with this id ? – Denys Séguret Commented Apr 9, 2013 at 15:25 -
5
Not sure what your point about
.bind()
is, you don't seem to be using it?this
will work in your example, because the wayeach()
calls the callback does set upthis
. What you do lose this way is binding of other local lexicals and that is often a reason to prefer the anonymous function, although you can convert lexicals into function parameters if you want. – drquicksilver Commented Apr 9, 2013 at 15:26 - 4 @RocketHazmat Not only is the first one more readable, it also es with the closure and thus the access to myVal. – Denys Séguret Commented Apr 9, 2013 at 15:27
3 Answers
Reset to default 5And 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) {}
}
}
You're not losing access to this
; you're losing access to myVal
because myVal
is not known inside myFunction
, mainly due to that function being defined in a scope 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);
});
}
This way if you have a lot of logic inside myFunction
, you can still separate it out and just call myFunction
from .each)
's callback. Not that myFunction
is being called with .call
because that way you can pass in an explicit value for this
(the first argument). Hence this
is the same this
that is inside the callback to .each
.
To be honest though, the first option is much more readable and you really aren't gaining much by splitting your code out like this.
this
in this context will be the same. The one thing you lose access to is myVal
. You are right that you can't use Function.bind
because that does not allow you to specify to keep the original (call time) this
Here's how you can pass myVal
and keep the same this
, using a modified version of Function.bind
, that we're calling 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's bind more than one argument, and it should be inserted 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's 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 Caillerie. The only difference is that we create a different version of Function.bind
that doesn't bind this
, just the arguments. Another benefit of this version is that you can choose where the insert the bound arguments;
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744733734a4590616.html
评论列表(0条)