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 environment, 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 environment need only provide bindings for names used freely in the original source code. For purposes of this scope analysis, a use of the direct
eval operator 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.
(This was pointed out by someone on es-discuss. Please find and link to that.)
eval()uating a function declaration or function expression defaults to non-strict, a strict function must present the source code of its body as beginning with a
“use strict” directive, even if the original function inherited its strictness from its context. This is the one case where the original local source code of the function is inadequate to satisfy this spec.
Thanks to David Flanagan who first raised this on es-discuss.
Remaining function_to_string strawman.