最近,我读了一篇文章,其中包含以下几行
var obj = {};
Array.prototype.push.call(obj, 'aaa', 'bbb', 'ccc');
console.log(obj);
{0: "aaa", 1: "bbb", 2: "ccc", length: 3}
我知道它尝试使用obj作为上下文并将其余部分作为参数传递。之前,我只是将每个项目推送到一个数组中。我很好奇这个实现背后的逻辑是什么。它如何设置索引作为值的每个键以及为什么'length'也会自动添加到对象中?感谢
答案 0 :(得分:2)
Because that's how push
works。大多数数组方法都是有意通用的,因此它们可以应用于其他对象,而不仅仅是数组。
当使用零个或多个参数item1,item2等调用push方法时,将执行以下步骤:
- 让 O 成为调用ToObject传递
醇>this
值作为参数的结果。
这只是确保this
是一个对象:var O = Object(this);
- 让 lenVal 成为使用参数“length”调用 O 的[[Get]]内部方法的结果。
醇>
var lenVal = O.length;
。在我们的情况下,lenVal
将为undefined
,因为该对象没有length
属性。
- 让 n 成为ToUint32( lenVal )。
醇>
将lenVal
转换为数字,并将结果分配给n
。 undefined
将转换为0
。
- 让 items 成为一个内部List,其元素按从左到右的顺序排列为传递给此函数调用的参数。
醇>
基本上var items = arguments;
。
- 重复,而项目不为空
醇>
- 从项中删除第一个元素,并让 E 成为元素的值。
- 使用参数ToString( n ), E 和{调用 O 的[[Put]]内部方法{1}}。
- 将n增加1。
这只是遍历true
中的所有条目,分配items
和O[String(n)] = E;
。这是您传递给push的每个参数都分配给对象的地方!
- 使用参数“length”, n 和
醇>n += 1
调用 O 的[[Put]]内部方法。
将true
设置为length
:n
。这是设置O.length = n;
的地方!
- 返回 n 。
醇>