For a function
Function.prototype.toString.call(fn) must return source code for a FunctionDeclaration or FunctionExpression that, if
eval()uated in an equivalent-enough lexical context, would result in a function with the same [[Call]] behavior as the present one. Note that the new function would have a fresh identity and none of the original’s properties, not even
.prototype. (The properties could of course be transferred by other means but the identity will remain distinct.)
This returned source code must not mention freely any variables that were not mentioned freely by the original function’s source code, even if these “extra” names were originally in scope. With this restriction, an equivalent-enough lexical context need only provide
evaloperator is statically considered a free usage of all variables in scope at that point.
Allowing FunctionExpression in the spec above acknowledges reality. All major JS engines will convert an anonymous function to an anonymous FunctionExpression, even though the ES3 and ES5 specs disallow it. This behavior is useful, so we should make it official. Note that a sufficient condition for meeting this specification is to always return precisely the function’s original source code.
Thanks to David Flanagan who first raised this on es-discuss.
Thanks to Luke Hoban for expanding the notion of lexical context to include strictness.
Remaining function_to_string strawman.