name property for built-in functions??

Allen Wirfs-Brock Allen.Wirfs-Brock at microsoft.com
Tue Mar 3 18:24:56 PST 2009


Strictly speaking, this issue seems to be more about Function.prototype.toString than it is about Function.prototype.name.

Here is what each of the 5 browsers in our regular test set does for each when called on a (new Function):

(new Function).toString ==> "function anonymous() { }" assorted whitespace/new line variations
   FF(3.0.6), Safari(3.1.2), Chrome(1.0) , IE (7):
 
(new Function).toString ==> "function (){}"  (with various new lines inserted)
   Opera(9.63)

(function() {}).toString() ==> "function (){}"  (with various new lines inserted)
   FF, Safari, Chrome, Opera

(function() {}).toString() ==> "(function (){})"  (note the outer parens)
   IE

(new Function).hasOwnProperty("name") ==> true
(new Function).name ==> "anonymous"
(function() {}).name ==> ""
FF, Chrome

(new Function).hasOwnProperty("name") ==> false
Opera, Safari, IE

Function.prototype.hasOwnProperty("name") ==> true
Function.prototype.name  ==> ""
   FF

Function.prototype.hasOwnProperty("name") ==> true
Function.prototype.name  ==> "Empty"
   Chrome

Function.prototype.hasOwnProperty("name") ==> false
   Safari, Opera, IE

ES3 says that Function.prototype.toString produces a string that has the syntax of a FunctionDeclaration and FunctionDeclaration must have an identifier in the function name position. All the implementation except for Opera comply and agree upon the name "anonymous" for anonymous functions created with (new Function).  This is a case where Opera is out of conformance with ES3 by generating what looks like a function expression rather than a function declaration. However, all of the browsers are out of conformance with ES3 for toString for anonymous functions created using a FunctionExpression.  IE throws in an extra set of parens in that case.

The Es3 extension of a name property for functions only appear to be implemented  by FF and Chrome, and they disagree about the name of Function.prototype. 

The ES specification of Function.prototype.toString clearly does not reflect reality. The goal is to achieve uniformity among implementations while minimizing impact upon existing code.  Given this, I propose that we modify the first paragraph of 15.2.4.2 (Function.prototype.toString) with the

An implementation-dependent >>>string<<< representation of the function is returned. This representation has the syntax of a >>>FunctionExpression<<<. Note in particular that the use and placement of white space, line terminators, and semicolons within the representation string is implementation-dependent. >>>If the function was created by evaluating a FunctionDeclaration then the returned representation must include the identifier from the FunctionDeclaration in the optional identifier position in the FunctionExpression.  If the function was created by a call to the standard built-in Function constructor then the name "anonymous" must occur in the optional identifier position of the returned string.  If the function was created by evaluating a FunctionExpression that did not include an identifier, by a get or set property assignment in an ObjectLiteral, or by a call to the Function.prototype.bind built-in method then no identifier is included in the returned representation.  If the function is a built-in function then the property name assigned to the function in this specification (or by the implementation if it is a non-standard function) is included in as the identifier in the returned representation.  If the function is a host object then whether or not an identifier is present is implementation defined.<<< 

(maybe I can work on the wording ;-) 

The above codifies what currently is most commonly implemented with some elaboration for new features in ES3.1 and should take care of the actual use case that Maciej identifier in the bug report.

Regarding, Function.prototype.name, it doesn't appear to be nearly so universally implemented.  Given that, I suggest we use the opportunity of defining it in ES3.1 to maximize its utility by providing more descriptive names than what is current generated by Function.prototype.toString. I'd prefer that we stick with what is in current ES3.1 draft which is:
   Defined by                           name
FunctionDeclaration                 the identifier from the declaration
FunctionExpression with name        the identifier from the function expression
FunctionExpresion w/o name          the empty string
Object literal get/set              "get <property name>" or "set <property name>"
Bound function                      "bind <target function name>" or " bind anonymous function"
(new Function)                       "new Function"*
Built-in                            specified name

*the current draft says "" but I consider this to be a bug.  I apparently lost this change when Word crashed on me Sunday :-(

>-----Original Message-----
>From: Brendan Eich [mailto:brendan at mozilla.com]
>Sent: Tuesday, March 03, 2009 3:25 PM
>To: Maciej Stachowiak
>Cc: Allen Wirfs-Brock; es-discuss at mozilla.org
>Subject: Re: name property for built-in functions??
>
>On Mar 3, 2009, at 2:39 PM, Maciej Stachowiak wrote:
>
>> Surprising though it may be, it seems that (new Function).name ===
>> "anonymous" may be relevant to Web compatibility. We changed
>> JavaScriptCore to match SpiderMonkey on this as a result of this bug:
>>
>> http://bugzilla.opendarwin.org/show_bug.cgi?id=7726
>
>I can't reach that hostname, but
>https://bugs.webkit.org/show_bug.cgi?id=7726
>  works.
>
>BTW, the ability to write a program whose entire source is "function
>() {}" is an old, pre-ES3 feature of SpiderMonkey that people *still*
>depend on, especially when using eval (not new Function) to generate a
>lambda from source.
>
>Per ES3 this should be a syntax error as Darin Adler pointed out in
>the bugs.webkit.org bug, but we have had to keep compatibility with
>what came before ES3 on this point. There's an API option
>(JSOPTION_ANONFUNFIX) to make this case an error per spec.
>
>
>> I strongly suspect code also depends on (function(){}).name==="" but
>> I don't have a clear-cut example handy.
>
>I voiced the same suspicion. I didn't know any web site depending on
>Function().name == "anonymous", though. What a world!
>
>/be



More information about the Es-discuss mailing list