12

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

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

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

4

1 回答 1

6

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

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

  1. array成为调用值的ToObject结果this
  2. func是调用with argument的[[Get]]内部方法的结果。array"join"
  3. 如果IsCallable(func)false,那么让func是标准的内置方法Object.prototype.toString(15.2.4.2)。
  4. 返回调用提供作为值和空参数列表的[[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并执行以下步骤:

  1. O是调用ToObjectthis值作为参数传递的结果。
  2. lenVal是调用with argument的[[Get]]内部方法的结果。O"length"
  3. len_ToUint32(lenVal).
  4. 如果separatorundefined,则separator设为单字符String ","
  5. 让。sep_ToString(separator)
  6. 如果lenzero,则返回空String
  7. element0是调用with argument的[[Get]]内部方法的结果。O"0"
  8. 如果element0undefinednull,则为RString;否则,RToString(element0).
  9. 设为k1。
  10. 重复,而k<len
    1. SString连接R和产生的值sep
    2. element是调用with argument的[[Get]]内部方法的结果。OToString(k)
    3. 如果elementundefinednull,则next设为空String;否则,nextToString(element).
    4. RString通过连接S和产生的值next
    5. 增加k1。
  11. 返回R

该方法的length属性join为 1。

注意join函数是故意通用的;它不要求它的this值是一个Array对象。因此,它可以转移到其他种类的对象中作为方法使用。函数能否join成功应用于宿主对象取决于实现。

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

于 2012-12-11T18:23:48.340 回答