2014-12-02 62 views
0

最近,我读到了以下行JavaScript对象与数组原型

var obj = {}; 
Array.prototype.push.call(obj, 'aaa', 'bbb', 'ccc'); 
console.log(obj); 
{0: "aaa", 1: "bbb", 2: "ccc", length: 3} 

我知道它会尝试使用OBJ的背景和经过,其余为参数的文章。之前,我只是用来将每个项目推送到一个数组中。我很好奇这个实现背后的逻辑是什么。它如何将索引设置为值的每个键以及为什么“长度”自动添加到对象?谢谢

+2

因为这push'如何'工作:http://es5.github.io/#x15.4.4.7 – 2014-12-02 17:57:36

+1

事实上,许多阵列方法是......“故意通用的,不要求他们的'this'值是一个Array对象',引用了同一个文档。 – raina77ow 2014-12-02 18:03:36

回答

2

Because that's how push works。大多数数组方法都是有意通用的,所以它们可以应用于其他对象,而不仅仅是数组。

当推方法被称为具有零个或多个参数ITEM1,ITEM2,等等,都采取以下步骤:

  1. ö是主叫ToObject传递this值的结果作为论据。

这只是确保this是一个对象:var O = Object(this);

  • lenVal是调用[[获取]]内部方法的结果O,参数“length”。
  • var lenVal = O.length;lenVal在我们的例子中将为undefined,因为该对象没有length属性。

  • ÑToUint32lenVal)。
  • lenVal转换为数字,并将结果n分配。 undefined将被转换为0

  • 是一个内部列表,其元素,在从左到右的顺序,被传递给该函数调用,该参数。
  • 基本上var items = arguments;

  • 重复,而不为空
    • 取下第一元件和让Ë是该元素的值。
    • 呼叫的ö与参数的[[把]]内部方法ToStringÑÈ,和true
    • 增加n加1。
  • 这仅仅遍历所有条目中items,分配O[String(n)] = E;n += 1。这是您传递给每个推送参数的地方!

  • 调用[[把]的ö与参数 “长度”,Ñ,和true内部方法。
  • lengthnO.length = n;。这是length设置的地方!

  • 返回Ñ
  • +0

    这是一个非常详细的解释。您的评论比ECMA5指令更具可读性。非常感谢 – eded 2014-12-02 18:48:14