Is it possible to create an array that will only allow objects of a certain to be stored in it? Is there a method that adds an element to the array I can override?
Asked
Active
Viewed 208 times
0
-
Rather than manipulate the array directly, create your own functions or methods that manipulate the array and you can condition the data however you want before actually putting it in the array. – jfriend00 Apr 05 '15 at 19:15
2 Answers
2
Yes you can, just override the push array of the array (let's say all you want to store are numbers than do the following:
var myArr = [];
myArr.push = function(){
for(var arg of arguments) {
if(arg.constructor == Number) Array.prototype.push.call(this, arg);
}
}
Simply change Number
to whatever constructor you want to match. Also I would probably add and else statement or something, to throw an error if that's what you want.
UPDATE:
Using Object.observe (currently only available in chrome):
var myArr = [];
Array.observe(myArr, function(changes) {
for(var change of changes) {
if(change.type == "update") {
if(myArr[change.name].constructor !== Number) myArr.splice(change.name, 1);
} else if(change.type == 'splice') {
if(change.addedCount > 0) {
if(myArr[change.index].constructor !== Number) myArr.splice(change.index, 1);
}
}
}
});
Now in ES6 there are proxies which you should be able to do the following:
var myArr = new Proxy([], {
set(obj, prop, value) {
if(value.constructor !== Number) {
obj.splice(prop, 1);
}
//I belive thats it, there's probably more to it, yet because I don't use firefox or IE Technical preview I can't really tell you.
}
});

Edwin Reynoso
- 1,511
- 9
- 18
1
Not directly. But you can hide the array in a closure and only provide your custom API to access it:
var myArray = (function() {
var array = [];
return {
set: function(index, value) {
/* Check if value is allowed */
array[index] = value;
},
get: function(index) {
return array[index];
}
};
})();
Use it like
myArray.set(123, 'abc');
myArray.get(123); // 'abc' (assuming it was allowed)

Oriol
- 274,082
- 63
- 437
- 513
-
That's pretty restrictive as it supports no array methods such as `.length` or `.slice()`, or `.forEach()` etc... In fact, you can't even iterate the elements in that object. Demonstrates a possible direction, but likely not practical as implemented. – jfriend00 Apr 05 '15 at 19:18
-
@jfriend00 Yes, those methods would be very useful. The implementation is left as an exercise for the reader :) – Oriol Apr 05 '15 at 19:21