我从 Chrome 开发人员工具的控制台中获得了以下跟踪:
> a = [1]
[1]
> b = [2, a]
[2, Array[1]]
> a.push(b)
2
> a.toString()
"1,2,"
似乎toString()
智能地跳过了对象图的递归部分。这是在某处记录的标准行为吗?
我从 Chrome 开发人员工具的控制台中获得了以下跟踪:
> a = [1]
[1]
> b = [2, a]
[2, Array[1]]
> a.push(b)
2
> a.toString()
"1,2,"
似乎toString()
智能地跳过了对象图的递归部分。这是在某处记录的标准行为吗?
[ECMA-262: 15.4.4.2]:
Array.prototype.toString ( )
调用该
toString
方法时,将执行以下步骤:
- 让
array
成为调用值的ToObject
结果this
。- 让
func
是调用with argument的[[Get]]
内部方法的结果。array
"join"
- 如果
IsCallable(func)
是false
,那么让func
是标准的内置方法Object.prototype.toString
(15.2.4.2)。- 返回调用提供作为值和空参数列表的
[[Call]]
内部方法的结果。func
array
this
注意该
toString
函数是故意通用的;它不要求它的this
值是一个Array
对象。因此,它可以转移到其他类型的对象中用作方法。函数能否toString
成功应用于宿主对象取决于实现。
所有这些基本上意味着结果是对 的调用Array.prototype.join()
,它在中定义15.4.4.5
并且不要求任何递归检测:
[ECMA-262: 15.4.4.5]:
Array.prototype.join (separator)
数组的元素被转换为
String
s,然后将这些String
s 连接起来,由分隔符的出现来分隔。如果未提供分隔符,则使用单个逗号作为分隔符。join 方法接受一个参数 ,
separator
并执行以下步骤:
- 让
O
是调用ToObject
将this
值作为参数传递的结果。- 让
lenVal
是调用with argument的[[Get]]
内部方法的结果。O
"length"
- 让
len
_ToUint32(lenVal).
- 如果
separator
是undefined
,则separator
设为单字符String
","
。- 让。
sep
_ToString(separator)
- 如果
len
是zero
,则返回空String
。- 让
element0
是调用with argument的[[Get]]
内部方法的结果。O
"0"
- 如果
element0
是undefined
或null
,则为R
空String
;否则,R
让ToString(element0)
.- 设为
k
1。- 重复,而
k
<len
- 让
S
是String
连接R
和产生的值sep
。- 让
element
是调用with argument的[[Get]]
内部方法的结果。O
ToString(k)
- 如果
element
是undefined
或null
,则next
设为空String
;否则,next
让ToString(element)
.- 让
R
是String
通过连接S
和产生的值next
。- 增加
k
1。- 返回
R
。该方法的
length
属性join
为 1。注意该
join
函数是故意通用的;它不要求它的this
值是一个Array
对象。因此,它可以转移到其他种类的对象中作为方法使用。函数能否join
成功应用于宿主对象取决于实现。
那么,这是一种标准保证的行为吗?不。