user4602228
user4602228

Reputation:

JS Apply Array Prototype "indexOf" and "splice" On Object Instead of Array

We have a simple object with methods

var o = {
   fn : (a)=>{}
}

We than add numerical indexed sub objects to it

o[0] = {};
o[1] = {};

So now we have a mixture of methods and numeric properties

o = {
   "0" : {}...
   "1" : {}...
   fn  : (a)=>{}
}

This is helpful for various reasons... seems totally legit and possible in JS.

We preferred an object with numeric properties, instead of an array with methods.

The Question : is there a way to get indexOf, splice, various Array.prototype methods to work with this?

We have tried stuff like :

[].indexOf.call(o,_index) // didn't work

...

Is the only solution would be to construct our object as an array, appending methods to it? or maybe there is another way to apply Array.prototype methods on an object?

Upvotes: 0

Views: 130

Answers (2)

Mark
Mark

Reputation: 92440

If you give you object a length property you can hack your way into the array methods through the back door. I suspect nobody would really advise doing this, but the way the JS spec is written to look for length and iterate over sequential numbers, many of these methods will work:

let o = {
  "0" : "zero",
  "1" : "one",
  length: 3,
  fn  : (a)=>{},
  "2" : "Two",
}

console.log(Array.prototype.slice.call(o, 1))

console.log(Array.prototype.indexOf.call(o, "Two"))

Array.prototype.splice.call(o, 1, 0, "Three")
// spliced in and adjusted length
console.log(o)

Upvotes: 1

Nina Scholz
Nina Scholz

Reputation: 386550

You could take Object.assign with an array as target. The result is an array with all array methods.

var o = { 0: 'foo', 1: 'bar', fn: a => {} };

console.log(Object.assign([], o).indexOf('bar'));

For IE, you could reduce the keys.

var o = { 0: 'foo', 1: 'bar', fn: a => {}, '1.1': 'wrong', '-1': 'wrong', 1e10: 'wrong' },
    array = Object.keys(o).reduce((r, i) => {
        if (isNaN(i) || +i < 0 || +i !== +i | 0) return r;
        r[i] = o[i];
        return r;
    }, []);

console.log(array.indexOf('bar'));
console.log(array);

Upvotes: 1

Related Questions