properties of function non-array 'arguments' do not match spec

VERIFIED INVALID

Status

()

Core
JavaScript Engine
--
minor
VERIFIED INVALID
15 years ago
15 years ago

People

(Reporter: Nathan Kurz, Assigned: rogerl (gone))

Tracking

Trunk
All
Linux
Points:
---

Firefox Tracking Flags

(Not tracked)

Details

Attachments

(1 attachment, 1 obsolete attachment)

(Reporter)

Description

15 years ago
User-Agent:       Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.3a) Gecko/20021207 Phoenix/0.5
Build Identifier: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.3a) Gecko/20021207 Phoenix/0.5

I started out thinking that 'arguments' was an array, as it is referred to in
the Netscape developer documentation at
http://developer.netscape.com/docs/manuals/js/core/jsref15/function.html#1193312,
but after reading bug #37211 and the associated spec I see that it is not
actually an array.  Instead, 10.1.8, I learned that 'arguments' is simply an
object with properties corresponding to the passed args:

  For each non-negative integer, arg, less than the value of the length
  property, a property is created with name ToString(arg) and property
  attributes {DontEnum}. The initial value of this property is the value
  of the corresponding actual parameter supplied by the caller.

If I access these properties using array type notation obj[prop], everything
works.  But if I try to access these properties using the standard obj.prop
notation, I get odd syntax error messages:

  function foo() {return arguments[0]} -> works as expected
  function foo() {return arguments.0}  -> Error: missing ; before statement

  function foo() {alert(arguments[0]} -> works as expected
  function foo() {alert(arguments.0)} -> Error: missing ) after argument list

While this seems like a bug, I'm not sure it needs to be fixed (although fixing
the developer documentation would be nice).  What I really would like would be
for 'arguments' to be an Array, but this is not what the spec provides. But in
case some is searching these bugs looking for a workaround (like I was), if you
want Array methods for 'arguments', you can create your own array and populate
it by iterating over 'arguments':

  var argArray = new Array(arguments.length);
  for (var i = 0; i < arguments.length; i++) {
    argArray[i] = arguments[i]};
  }




Reproducible: Always

Steps to Reproduce:

Comment 1

15 years ago
Thank you for such a well-researched and well-written bug report.

The issue you raise applies to any JavaScript object, not just the
|arguments| object inside a function. No object allows the syntax |obj.1|
By contrast, the syntax |obj[1]| is OK. 


From the ECMA-262 Ed.3 standard:

-----------------------------------------------------------------------------
11.2.1 Property Accessors
Properties are accessed by name, using either the dot notation:
MemberExpression . Identifier

or the bracket notation:
MemberExpression [ Expression ]

The dot notation is explained by the following syntactic conversion:
MemberExpression . Identifier is identical in its behaviour to
MemberExpression [ <identifier-string> ]

where <identifier-string> is a string literal containing
the same sequence of characters as the Identifier.

The production MemberExpression : MemberExpression [ Expression ]
is evaluated as follows:
1. Evaluate MemberExpression.
2. Call GetValue(Result(1)).
3. Evaluate Expression.
4. Call GetValue(Result(3)).
5. Call ToObject(Result(2)).
6. Call ToString(Result(4)).
7. Return a value of type Reference whose base object is Result(5)
   and whose property name is Result(6).
-----------------------------------------------------------------------------



This shows that the two syntaxes |obj.prop| and |obj[prop]| are not
completely equivalent. In the former, |prop| must be an identifier.
In particular, it cannot be a literal. That is why obj.1 doesn't work:
|1| is a numeric literal and not permitted as an identifier:

js> var 1 = "Hello";
47: SyntaxError: missing variable name:
47: var 1 = "Hello";
47: ....^

js> var '1' = "Hello";
48: SyntaxError: missing variable name:
48: var '1' = "Hello";
48: ....^


By contrast, in the latter syntax, |prop| is interpreted as a string
expression, and literal values are appropriate. When you do |obj[1]|,
the numeric literal |1| is converted to the string literal "1",
which may be used as a property name.

Comment 2

15 years ago
Created attachment 109457 [details]
HTML testcase

Comment 3

15 years ago
Created attachment 109460 [details]
HTML testcase (more precise version)

Updated

15 years ago
Attachment #109457 - Attachment is obsolete: true

Comment 4

15 years ago
The Netscape and Microsoft implementations of JavaScript agree on this.
The HTML testcase fails in both Mozilla and in IE6, with the same error: 

                Moz: "Missing ; before statement"
                IE6: "Expected ';'" 

Have to mark this one invalid; sorry - both implementations of JavaScript
are going according to spec.
Status: UNCONFIRMED → RESOLVED
Last Resolved: 15 years ago
Resolution: --- → INVALID

Comment 5

15 years ago
Marking Verified -
Status: RESOLVED → VERIFIED
You need to log in before you can comment on or make changes to this bug.