我们有一个带有方法的简单对象
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 :(得分: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)