We have created a Bag constructor that can accept any number of arguments and will create getters for each. We made use of the arguments property of functions to access the items that were passed in to the constructor.
function Bag() {
for (var i = 0; i < arguments.length; i++) {
(function(that, i, args) {
that["getitem" + i] = function() {
return args[i];
};
})(this, i, arguments);
}
}
Would the same techniques work if we passed in an array of values explicitly, rather than using the arguments property?
function Bag(itemArray) {
for (var i = 0; i < itemArray.length; i++) {
(function(that, i, args) {
that["getitem" + i] = function() {
return args[i];
};
})(this, i, itemArray);
}
}
var bag = new Bag(["Apple", "Banana", "Cucumber"]);
By replacing arguments with itemArray we have changed the constructor so that it now accepts a single array rather than a variable number of arguments. But part of our work earlier was overcoming problems caused by arguments being a special word. Now that we have removed it, maybe we can tidy the code a little.
function Bag(itemArray) {
for (var i = 0; i < itemArray.length; i++) {
(function(that, i) {
that["getitem" + i] = function() {
return itemArray[i];
};
})(this, i);
}
}
var bag = new Bag(["Apple", "Banana", "Cucumber"]);
We can restore the intended context to the inner function by using the call() method. That will make explicit our choice of context, remove the need for the switch to that and tighten the code nicely.
function Bag(itemArray) {
for (var i = 0; i < itemArray.length; i++) {
(function(i) {
this["getitem" + i] = function() {
return itemArray[i];
};
}).call(this, i);
}
}
var bag = new Bag(["Apple", "Banana", "Cucumber"]);