If you don't want t change Array.prototype
, the only really feasible solution is adding the methods to the specific array object:
function doSomething() {}
function doOther() {}
function wrap(array) {
array.doSomething = doSomething;
array.doOther = doOther;
return array;
}
Note that I'm not defining doSomething()
and doOther()
within wrap()
- otherwise, we would create new function objects on each call, which is highly inefficient.
A more sophisticated variant would be the following:
function doSomething() {}
function doOther() {}
function wrap(array) {
if(this instanceof arguments.callee) {
this.doSomething = doSomething;
this.doOther = doOther;
}
else {
arguments.callee.prototype = array;
return new arguments.callee;
}
}
Here, we create a new wrapper object (and don't add properties to the array itself). The wrapper object will still have access to all the array's properties. There's a slight catch, though:
var foo = wrap([1,2,3]);
document.writeln(foo.length); // writes 3
foo.push(4);
document.writeln(foo.length); // writes 4 in FF, 3 in IE
foo[4] = 5;
foo[5] = 6;
document.writeln(foo.length); // still writes 4?!
Using foo[4] =
will access our wrapper object and the properties 4
and 5
will be set there and not in the array - therefore, its length property won't be updated. In IE, calling push()
will already fail to correctly update the array...
If your wrapper object doesn't need to 'reroute' calls to the array object, there are other solutions using closures - sktrdie's first example is one of these. I'd argue against them because they will create new function objects with every call as well. What I would do:
function wrap(array) {
if(this instanceof arguments.callee)
this.array = array;
else return new arguments.callee(array);
}
wrap.prototype.doSomething = function() {};
wrap.prototype.doOther = function() {};
Here, you can access the array in doSomething()
and doOther()
via this.array
.