我从 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]]内部方法的结果。funcarraythis注意该
toString函数是故意通用的;它不要求它的this值是一个Array对象。因此,它可以转移到其他类型的对象中用作方法。函数能否toString成功应用于宿主对象取决于实现。
所有这些基本上意味着结果是对 的调用Array.prototype.join(),它在中定义15.4.4.5并且不要求任何递归检测:
[ECMA-262: 15.4.4.5]:Array.prototype.join (separator)数组的元素被转换为
Strings,然后将这些Strings 连接起来,由分隔符的出现来分隔。如果未提供分隔符,则使用单个逗号作为分隔符。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).- 设为
k1。- 重复,而
k<len
- 让
S是String连接R和产生的值sep。- 让
element是调用with argument的[[Get]]内部方法的结果。OToString(k)- 如果
element是undefined或null,则next设为空String;否则,next让ToString(element).- 让
R是String通过连接S和产生的值next。- 增加
k1。- 返回
R。该方法的
length属性join为 1。注意该
join函数是故意通用的;它不要求它的this值是一个Array对象。因此,它可以转移到其他种类的对象中作为方法使用。函数能否join成功应用于宿主对象取决于实现。
那么,这是一种标准保证的行为吗?不。