Method # 1
function transform(ar) {
var alStr = [];
for(var i=0; i<ar.length; i++) {
alStr[i] = (function(v) {
return (function() {
return v;
});
}(ar[i]));
}
return alStr;
}
var a = ["a", 24, { foo: "bar" }];
var b = transform(a);
a[1];
b[1]();
Method # 2
function transform(ar) {
var alStr = [];
for(var a in ar) {
var O = function() {
return a;
}
alStr.push(O);
}
return alStr;
}
var a = ["a", 24, { foo: "bar" }];
var b = transform(a);
a[1];
b[1]();
The above mentioned methods are used to convert an array objects into individual functions which on execution return the specific array object. Want to know why method #1 works and method #2 doesnt.
In Method #2 there are two problems:
You are returning the key name,
a
, rather than the array value,ar[a]
. That is, rather thanreturn a;
you wantreturn ar[a];
.The function will always refer to the last value looped through because it references the same scope object. To create a new scope object you will need a closure, a
with
block, or a bound function.With a closure:
With a
with
block:With a bound function:
Peter Olson is correct. However, the more modern (correct?) way of doing this is by using
function.bind(obj, val)
. Introduced somewhat recently,function.bind
allows you to pass variables by value and in certain contexts. Read more here.So, you could write something like this:
This is a more correct paradigm due to the fact that initiating closures has very clear implications. Using bind, however, tends to be a functional approach to be used specifically when function calling (in particular contexts or with particular stipulations).
Using a with block also has some downsides (there are plenty of questions about it).
Bonus: If you wanted
b
to also represent subsequent changes to thea
array, this solution solves that problem: