在javascript的内置函数中进行循环检测

时间:2012-12-11 18:14:54

标签: javascript

我从Chrome开发者工具的控制台获得了以下跟踪:

> a = [1]
[1]
> b = [2, a]
[2, Array[1]]
> a.push(b)
2
> a.toString()
"1,2,"

似乎toString()智能地跳过了对象图的递归部分。这是在某处记录的标准行为吗?

1 个答案:

答案 0 :(得分:6)

  

[ECMA-262: 15.4.4.2]: Array.prototype.toString ( )

     

调用toString方法时,将执行以下步骤:

     
      
  1. array成为ToObjectthis的结果。
  2.   
  3. func成为使用参数[[Get]]调用array "join"内部方法的结果。
  4.   
  5. 如果IsCallable(func)false,则让func成为标准的内置方法Object.prototype.toString(15.2.4.2)。
  6.   
  7. 返回调用[[Call]] func提供array的{​​{1}}内部方法作为this值和空参数列表的结果。
  8.         

    注意 toString函数是故意通用的;它不要求其this值为Array对象。因此,它可以转移到其他类型的对象以用作方法。 toString函数是否可以成功应用于宿主对象是依赖于实现的。

所有这些基本上意味着结果是对Array.prototype.join()的调用,15.4.4.5中定义了[ECMA-262: 15.4.4.5]:并且不强制要求任何递归检测:

  

Array.prototype.join (separator) String

     

数组的元素将转换为String s,然后连接这些separator,由分隔符的出现分隔。如果未提供分隔符,则使用单个逗号作为分隔符。

     

join方法接受一个参数O,并执行以下步骤:

     
      
  1. ToObject成为调用this传递lenVal值作为参数的结果。
  2.   
  3. [[Get]]成为使用参数O调用"length" len内部方法的结果。
  4.   
  5. ToUint32(lenVal).成为separator
  6.   
  7. 如果undefinedseparator,请String为单字符"," sep
  8.   
  9. ToString(separator)成为len
  10.   
  11. 如果zeroString,请返回空element0
  12.   
  13. [[Get]]成为使用参数O调用"0" element0内部方法的结果。
  14.   
  15. 如果undefinednullR,请String为空R;否则,让ToString(element0)k
  16.   
  17. k为1。
  18.   
  19. 重复,同时len< S   
        
    1. String成为Rsep连接产生的element值。
    2.   
    3. [[Get]]成为使用参数O调用ToString(k) element内部方法的结果。
    4.   
    5. 如果undefinednullnext,请String为空next;否则,让ToString(element)R
    6.   
    7. 通过连接StringSnext生成k值。
    8.   
    9. R增加1。
    10.   
  20.   
  21. 返回length
  22.         

    join方法的join属性为1。

         

    注意 this函数是故意通用的;它不要求其Array值为join对象。因此,它可以转移到其他种类的对象以用作方法。 {{1}}函数是否可以成功应用于宿主对象是依赖于实现的。

那么,这是一种标准保证的行为吗?