quirky arguments
Monday, 22. January 2007, 14:52:35
Here is the issue in a minimal snippet of JavaScript:
function test(){}
test.arguments='something';
test();
alert(test.arguments); // test.arguments is now null ??so..? Inside the function body we have a local variable called "arguments", but this variable also becomes a property of the function itself, and is subsequently reset to null. Consider
function test(){ alert(arguments==test.arguments); }which says "true" and shows us that the local variable and the function property refer to the same object.
Some side-effects of this implementation include:
- "arguments" is a reserved word as function property name, it can not be used
- We can work out whether a function has been called by a script or not! Consider
Function.prototype.arguments=true; function test(){}; . . /* function definitions and calls here */ . var testWasCalled = ! test.arguments;
"testWasCalled" is now true if and only if the script has used the "test" function during its execution. Might be a handy trick for trying to optimise large scripts
..but where in the spec is this specified? In other words, is it a bug or a feature?
Or is JavaScript something else? Wikipedia says, "JavaScript is the name of Netscape Communications Corporation's implementation of the ECMAScript standard".
Here's what ECMA-262 says:
"This ECMA Standard is based on several originating technologies, the most well known being JavaScript (Netscape) and JScript (Microsoft)."
"This Standard defines the ECMAScript scripting language."
At least the situation is better than it is with Python, Perl, Ruby, and PHP.
By HeroreV, # 22. January 2007, 17:44:53
http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Function:arguments
http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Functions:arguments
It was deprecated in Javascript 1.4, which I guess is because it's not in ECMAscript. But browsers generally implement Javascript, or some variant with an added goto.
By unfortunately, # 22. January 2007, 18:41:06
My guess is that it's something to do with the setting up of function code's execution context (ECMA 262 section 10.2.3), but I don't have the time to bend my head around the specification today.
However: the Mozilla documentation states that it is an error to attempt to access the "arguments" property outside of a function declaration. So the code given has, by definition, unspecified behaviour, which is why it's not specified anywhere :-)
By nickfitz, # 22. January 2007, 21:47:38
Btw.
Try it in Opera :)
By _Grey_, # 23. January 2007, 02:37:40
In those browsers (didn't check others), it seems you cannot really change the arguments property of a function, and it remains null, whether you call it or not.
By splintor, # 23. January 2007, 06:26:07
"When control enters an execution context for function code, an object called the activation object is created and associated with the execution context. The activation object is initialised with a property
with name arguments and attributes { DontDelete }. The initial value of this property is the arguments object described below.
The activation object is then used as the variable object for the purposes of variable instantiation."
So, the arguments variable inside a function call should share the scope of any variabled declared inside the function call. If function locals were in the same scope as arguments that would mean this shoul alert true:
function foo() {
var test = true;
alert(foo.test == "asdf");
}
It doesn't, it's undefined. So either, the local is in the wrong scope, or arguments is in the wrong scope. Either way it's a bug.
By runeh, # 23. January 2007, 09:22:08
javascript:function test(){};test.arguments='something';alert(test.arguments);test();alert(test.arguments);//Opera:
// -> something
// -> null
// FF & IE6:
// -> null
// -> null
By _Grey_, # 23. January 2007, 18:19:04
splintor: interesting. Basically what IE and Firefox do is to have a readOnly Function.arguments property, returning "null" unless the function is running and pointing to the local arguments object when it does.
..looking at some of the stranger code in this script:
http://www.banquedirecte.fr/include/FormCheck.js
you can also see the related Netscape JS feature of referencing arguments of a function directly with a function[n] syntax. Look for stuff like
arguments.caller[4] ? Weird, weird.. Luckily IE doesn't support that so we've been spared seeing this stuff widely used
By hallvors, # 28. January 2007, 15:04:16
I don't really see a reason for not using "arguments" as a fully qualified Array. Of course, I'd rather see an "Arguments" object from which "arguments" inherit, but this is a temporary "fix". I think "arguments" should be mutable, though...
This creates apparent problems, of course, as
would do strange things if
(which is probably why you got problems with the mentioned JS libraries), but I'd consider this a weakness of the language anyways (is it that hard to implement a way of marking a property "dontEnum"?)...
Imho I read somewhere on bugzilla that they just deprecated it in favor of the IE-version: "caller" is not a property of "arguments", but rather of the function (or something like that). Regarding the weird caller[4] syntax, I think IE doesn't understand any of that.
By _Grey_, # 29. January 2007, 09:04:28
"The value of the arguments property is normally null if there is no outstanding invocation of the function in progress (that is, the function has been called but has not yet returned). When a non-internal Function object (15.3.2.1) is invoked, its arguments property is “dynamically bound” to a newly created object that contains the arguments on which it was invoked (see 10.1.6 and 10.1.8). Note that the use of this property is discouraged; it is provided principally for compatibility with existing old code."
From ECMA-262 1st edition, 10.1.6:
"If the function object being invoked has an arguments property, let x be the value of that property; the activation object is also given an internal property [[OldArguments]] whose initial value is x; otherwise, an arguments property is created for the function object but the activation object is not given an
[[OldArguments]] property."
"When a value is to be returned from the call to a function, its activation object is no longer needed and may be permanently decommissioned. At this time, if the activation object has no [[OldArguments]] property, then the arguments property of the function object is deleted; otherwise, the value of the [[OldArguments]] property of the activation object is stored into the arguments property of the function object (an arguments property is created for the function object if necessary)."
Of course, all of this was removed in 1998.
By unfortunately, # 14. February 2007, 12:15:16
By hallvors, # 9. March 2007, 15:08:10