最近,我读到一篇文章,有以下几行内容
var obj = {};
Array.prototype.push.call(obj, 'aaa', 'bbb', 'ccc');
console.log(obj);
{0: "aaa", 1: "bbb", 2: "ccc", length: 3}
我知道它尝试使用 obj 作为上下文并将其余部分作为参数传递。以前,我只习惯将每个项目推入数组中。我很好奇这个实现背后的逻辑是什么。它如何将索引设置为值的每个键以及为什么“长度”也会自动添加到对象中?谢谢
push
的工作原理。大多数数组方法都是有意通用的,因此它们可以应用于其他对象,而不仅仅是数组。
当使用零个或多个参数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 为一个内部列表,其元素按从左到右的顺序是传递给此函数调用的参数。
基本上
var items = arguments;
。
- 重复,同时items不为空
- 从 items 中删除第一个元素,并让 E 为该元素的值。
- 使用参数 ToString(n)、E 和
true
调用O的 [[Put]] 内部方法。- 将 n 加 1。
这只是迭代
items
中的所有条目,分配 O[String(n)] = E;
和 n += 1
。这是您传递给 Push 的每个参数都被分配给对象的地方!
- 使用参数“length”、n和
true
调用O的[[Put]]内部方法。
将
length
设置为 n
:O.length = n;
。这是设置length
的地方!
- 返回n。