Подтвердить что ты не робот

Обнаружение петли в встроенных функциях javascript

Я получил следующий след из консоли разработчика Chrome:

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

Кажется, что toString() интеллектуально пропустил рекурсивную часть графа объектов. Это где-то стандартное поведение?

4b9b3361

Ответ 1

[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 как значение 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 затем объединяются, разделяются вхождениями разделителя. Если разделитель не предусмотрен, в качестве разделителя используется одна запятая.

Метод join принимает один аргумент separator и выполняет следующие шаги:

  • Пусть O является результатом вызова ToObject, передающего значение this в качестве аргумента.
  • Пусть lenVal является результатом вызова внутреннего метода [[Get]] O с аргументом "length".
  • Пусть len be ToUint32(lenVal).
  • Если separator - undefined, пусть separator - односимвольный String ",".
  • Пусть sep be ToString(separator).
  • Если len - zero, верните пустой String.
  • Пусть element0 является результатом вызова внутреннего метода [[Get]] O с аргументом "0".
  • Если element0 - undefined или null, пусть R - пустой String; в противном случае пусть R be ToString(element0).
  • Пусть k будет 1.
  • Повторите, а k < len
    • Пусть S - значение String, созданное путем объединения R и sep.
    • Пусть element является результатом вызова внутреннего метода [[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 успешно применяться к объекту хоста, зависит от реализации.

Итак, это стандартно-гарантированное поведение? Нет.