Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loop detection in javascript's built-in functions

Tags:

javascript

I obtained the following trace from Chrome developer tool's console:

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

It seems the toString() intelligently skipped the recursive part of the object graph. Is this a standard behavior documented somewhere?

like image 369
billc.cn Avatar asked Dec 11 '12 18:12

billc.cn


People also ask

What is the functionality of for loop?

A "For" Loop is used to repeat a specific block of code a known number of times. For example, if we want to check the grade of every student in the class, we loop from 1 to that number. When the number of times is not known before hand, we use a "While" loop.

What are the 3 parts of a for loop in JavaScript?

The For-EndFor Statement Structure Another method of performing looping in your scripts is by using the For-EndFor looping statements. Similar to a While loop, a For loop consists of three parts: the keyword For that starts the loop, the condition being tested, and the EndFor keyword that terminates the loop.


1 Answers

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

When the toString method is called, the following steps are taken:

  1. Let array be the result of calling ToObject on the this value.
  2. Let func be the result of calling the [[Get]] internal method of array with argument "join".
  3. If IsCallable(func) is false, then let func be the standard built-in method Object.prototype.toString (15.2.4.2).
  4. Return the result of calling the [[Call]] internal method of func providing array as the this value and an empty arguments list.

NOTE The toString function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method. Whether the toString function can be applied successfully to a host object is implementation-dependent.

All of this basically means that the result is a call to Array.prototype.join(), which is defined in 15.4.4.5 and doesn't mandate any recursion detection:

[ECMA-262: 15.4.4.5]: Array.prototype.join (separator)

The elements of the array are converted to Strings, and these Strings are then concatenated, separated by occurrences of the separator. If no separator is provided, a single comma is used as the separator.

The join method takes one argument, separator, and performs the following steps:

  1. Let O be the result of calling ToObject passing the this value as the argument.
  2. Let lenVal be the result of calling the [[Get]] internal method of O with argument "length".
  3. Let len be ToUint32(lenVal).
  4. If separator is undefined, let separator be the single-character String ",".
  5. Let sep be ToString(separator).
  6. If len is zero, return the empty String.
  7. Let element0 be the result of calling the [[Get]] internal method of O with argument "0".
  8. If element0 is undefined or null, let R be the empty String; otherwise, Let R be ToString(element0).
  9. Let k be 1.
  10. Repeat, while k < len
    1. Let S be the String value produced by concatenating R and sep.
    2. Let element be the result of calling the [[Get]] internal method of O with argument ToString(k).
    3. If element is undefined or null, Let next be the empty String; otherwise, let next be ToString(element).
    4. Let R be a String value produced by concatenating S and next.
    5. Increase k by 1.
  11. Return R.

The length property of the join method is 1.

NOTE The join function is intentionally generic; it does not require that its this value be an Array object. Therefore, it can be transferred to other kinds of objects for use as a method. Whether the join function can be applied successfully to a host object is implementation-dependent.

So, is it a standard-guaranteed behaviour? No.

like image 185
Lightness Races in Orbit Avatar answered Oct 30 '22 06:10

Lightness Races in Orbit