ES proposal: Function.prototype.toString revision

By Axel Rauschmayer

The ECMAScript proposal “Function.prototype.toString revision” by Michael Ficarra is currently at stage 3. It brings two major improvements compared to ES2016:

  • If a function was created via ECMAScript source code, toString() must return that source code. In ES2016, whether to do so is left up to engines.

  • In ES2016, if toString() could not create syntactically valid ECMAScript code, it had to return a string for which eval() throws a SyntaxError. In other words, eval() must not be able to parse the string. This requirement was forward-incompatible – whatever string you come up with, you can never be completely sure that a future version of ECMAScript doesn’t make it syntactically valid.

The algorithm

The proposal distinguishes:

  • Functions defined via ECMAScript code: toString() must return their original source code. The following two kinds of line breaks are converted to Unix-style 'n' line breaks:

    • Windows: 'rn'
    • Classic macOS: 'r'

      toString() may return code that is only syntactically valid within its syntactic context:

          > class C { foo() { /*hello*/ } }
          > C.prototype.foo.toString()
          'foo() { /*hello*/ }'
      
  • Built-in function objects, bound function exotic objects and functions not defined via ECMAScript code: toString() must return:

        "function" BindingIdentifier? "(" FormalParameters ") { [native code] }"
    

    If a function has a name, it must appear in the result; the parameters are optional. For example:

        > Math.pow.toString()
        'function pow() { [native code] }'
    
  • If the receiver (this) is not callable, throw a TypeError.

Source:: 2ality