У нас есть простой объект с методами

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

Затем мы добавляем в него числовые индексированные суб-объекты.

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

Так что теперь у нас есть смесь методов и числовых свойств

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

Это полезно по разным причинам ... кажется вполне законным и возможным в JS.

Мы предпочли объект с числовыми свойствами, а не массив с методами.

Вопрос: есть ли способ получить indexOf, splice, различные Array.prototype методы для работы с этим?

Мы пробовали такие вещи, как:

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

...

Разве единственным решением было бы построить наш объект как массив, добавив к нему методы? или, может быть, есть другой способ применить методы Array.prototype к объекту?

0
user4602228 17 Апр 2019 в 10:56

2 ответа

Лучший ответ

Если вы дадите объекту length свойство, вы можете взломать методы массива через черный ход. Я подозреваю, что никто на самом деле не посоветует сделать это, но способ написания спецификации JS для поиска length и итерации последовательных чисел, многие из этих методов будут работать:

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)
1
Mark Meyer 17 Апр 2019 в 08:11

Вы можете взять Object.assign с массивом в качестве цели. Результатом является массив со всеми методами массива.

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

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

Для IE вы можете уменьшить ключи.

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);
1
Nina Scholz 17 Апр 2019 в 08:11