我从Chrome开发者工具的控制台获得了以下跟踪:
> a = [1]
[1]
> b = [2, a]
[2, Array[1]]
> a.push(b)
2
> a.toString()
"1,2,"
似乎toString()
智能地跳过了对象图的递归部分。这是在某处记录的标准行为吗?
答案 0 :(得分:6)
[ECMA-262: 15.4.4.2]:
Array.prototype.toString ( )
调用
toString
方法时,将执行以下步骤:
- 让
array
成为ToObject
值this
的结果。- 让
func
成为使用参数[[Get]]
调用array
"join"
内部方法的结果。- 如果
IsCallable(func)
为false
,则让func
成为标准的内置方法Object.prototype.toString
(15.2.4.2)。- 返回调用
醇>[[Call]]
func
提供array
的{{1}}内部方法作为this
值和空参数列表的结果。注意
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
,并执行以下步骤:
- 让
ToObject
成为调用this
传递lenVal
值作为参数的结果。- 让
[[Get]]
成为使用参数O
调用"length"
len
内部方法的结果。- 让
ToUint32(lenVal).
成为separator
- 如果
undefined
为separator
,请String
为单字符","
sep
。- 让
ToString(separator)
成为len
。- 如果
zero
为String
,请返回空element0
。- 让
[[Get]]
成为使用参数O
调用"0"
element0
内部方法的结果。- 如果
undefined
为null
或R
,请String
为空R
;否则,让ToString(element0)
为k
。- 让
k
为1。- 重复,同时
len
<S
- 让
String
成为R
和sep
连接产生的element
值。- 让
[[Get]]
成为使用参数O
调用ToString(k)
element
内部方法的结果。- 如果
undefined
为null
或next
,请String
为空next
;否则,让ToString(element)
为R
。- 通过连接
String
和S
,next
生成k
值。- 将
R
增加1。- 返回
醇>length
。
join
方法的join
属性为1。注意
this
函数是故意通用的;它不要求其Array
值为join
对象。因此,它可以转移到其他种类的对象以用作方法。 {{1}}函数是否可以成功应用于宿主对象是依赖于实现的。
那么,这是一种标准保证的行为吗? 否强>