Is there a way to get a get/set behaviour on an array? I imagine something like this:
var arr = [\'one\', \'two\', \'three\'];
var _arr = new Array();
for (
Why not create a new class for the inner objects?
var a = new Car();
function Car()
{
// here create the setters or getters necessary
}
And then,
arr = new Array[a, new Car()]
I think you get the idea.
I looked up in John Resig's article JavaScript Getters And Setters, but his prototype example didn't work for me. After trying out some alternatives, I found one that seemed to work. You can use Array.prototype.__defineGetter__
in the following way:
Array.prototype.__defineGetter__("sum", function sum(){
var r = 0, a = this, i = a.length - 1;
do {
r += a[i];
i -= 1;
} while (i >= 0);
return r;
});
var asdf = [1, 2, 3, 4];
asdf.sum; //returns 10
Worked for me in Chrome and Firefox.
It is possible to create setters for each element of an array, but there is one limitation: you would not be able to directly set array elements for indexes that are outside the initialized region (e.g. myArray[2] = ... // wouldn't work if myArray.length < 2
) Using the Array.prototype functions will work. (e.g. push, pop, splice, shift, unshift.) I give an example of how to accomplish this here.
I hope it helps.
Object.extend(Array.prototype, {
_each: function(iterator) {
for (var i = 0; i < this.length; i++)
iterator(this[i]);
},
clear: function() {
this.length = 0;
return this;
},
first: function() {
return this[0];
},
last: function() {
return this[this.length - 1];
},
compact: function() {
return this.select(function(value) {
return value != undefined || value != null;
}
);
},
flatten: function() {
return this.inject([], function(array, value) {
return array.concat(value.constructor == Array ?
value.flatten() : [value]);
}
);
},
without: function() {
var values = $A(arguments);
return this.select(function(value) {
return !values.include(value);
}
);
},
indexOf: function(object) {
for (var i = 0; i < this.length; i++)
if (this[i] == object) return i;
return -1;
},
reverse: function(inline) {
return (inline !== false ? this : this.toArray())._reverse();
},
shift: function() {
var result = this[0];
for (var i = 0; i < this.length - 1; i++)
this[i] = this[i + 1];
this.length--;
return result;
},
inspect: function() {
return '[' + this.map(Object.inspect).join(', ') + ']';
}
}
);
You can add whatever methods you like to an Array
, by adding them to Array.prototype
. Here's an example that adds a getter and setter
Array.prototype.get = function(index) {
return this[index];
}
Array.prototype.set = function(index, value) {
this[index] = value;
}
Array access is no different to normal property access. array[0]
means array['0']
, so you can define a property with name '0'
and intercept access to the first array item through that.
However, that does make it impractical for all but short, more-or-less-fixed-length Arrays. You can't define a property for “all names that happen to be integers” all in one go.