为什么[] .slice.call()返回“空插槽”?

时间:2019-03-31 04:54:22

标签: javascript

我正在尝试将复杂的对象包装在长度为1的数组中(即,该对象是数组中的唯一条目),并希望在类构造函数中做到这一点。 。 。为了到达那里,我一直在玩[] .slice.call(),当我出于测试目的而玩耍时,我在控制台中尝试了以下操作:

foo = {"a":{"a1":1},"b":{"b1":2},length: 2};
[].slice.call(foo);

我得到了一个长度为2的数组,其中包含“两个空插槽”。

鉴于[].slice.call({"a": 1, "b": 2, length: 2}产生了[1, 2],我本来希望得到长度为2的数组,如下所示: [{“ a1”:1},{“ b1”:2}],而不是“两个空插槽”。 [] .slice.call是否仅适用于“一维”对象,还是发生了其他事情?预先非常感谢,如果有人可以澄清一下!

2 个答案:

答案 0 :(得分:3)

slice将仅迭代对象的数字索引属性。参见spec

  
      
  1. 让relativeStart为ToInteger(start)。
  2.   

(因此,如果startundefined,就像在没有参数的情况下调用slice时,relativeStart0

然后,它将遍历从relativeStart(如果relativeStart为负,则为0)到对象的length属性值的数字索引:

  
      
  1. 如果relativeStart为负,则令k为max((len + relativeStart),0);否则让k为min(relativeStart,len)。
  2.   
     

8。如果relativeEnd为负,则将final为max((len + relativeEnd),0);否则让final为min(relativeEnd,len)。

     

10。重复,而k      

      
  • (将obj [k]推入正在创建的新的类似数组的对象中)
  •   

所以:

  

[]。slice.call是否仅适用于“一维”对象,还是有其他事情发生?

它仅适用于具有数字属性的对象。如果您具有非数字属性,则不会使用slice来迭代它们。

如果您想

  

将一个复杂的对象包装在长度为1的数组中(即,该对象是数组中的唯一条目)

然后只需使用[foo],例如:

const foo = {"a":{"a1":1},"b":{"b1":2},length: 2};
const wrappedFoo = [foo];
console.log(wrappedFoo);

  

是否有一种“简便”的方法可以将{“ a”:{“ a1”:“ foo”},“ b”:{“ b1”:“ bar”}}转换为[{“ a1”:“ foo “},{” b1“:” bar“}]?

使用Object.values将对象的值提取到数组中:

const obj = {"a":{"a1":"foo"},"b":{"b1":"bar"}};
const arr = Object.values(obj);
console.log(arr);

答案 1 :(得分:1)

您将用作object参数的call()作为this的{​​{1}}参数传递,它将仅在对象的数字属性上起作用,如已经提到 CertainPerformance 。如果使用数字属性,它将按预期工作:

slice()
let foo1 = {"0": 1, "1": 2, length: 2};
console.log([].slice.call(foo1));

let foo2 = {"0": {"a1":1}, "1": {"b1":2}, length: 2};
console.log([].slice.call(foo2));

但这是获得Object.values()已经给您的东西的一种罕见方法:

.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}
let foo1 = {"0": 1, "1": 2};
console.log(Object.values(foo1));

let foo2 = {"0": {"a1":1}, "1": {"b1":2}};
console.log(Object.values(foo2));