JS在对象而不是数组上应用数组原型“ indexOf”和“ splice”

时间:2019-04-17 07:56:59

标签: javascript arrays object

我们有一个带有方法的简单对象

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方法的方法?

2 个答案:

答案 0 :(得分:2)

您可以将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 :(得分: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)