Reputation: 1110
There is a piece of code of online tutorial
sayHi(1);
function sayHi(x); {
alert(x); // 1
[].shift.call(arguments);
alert(x); // undefined, no x any more :/
}
In tutorial it says:
Array methods which modify arguments also modify local parameters.
Actually, the modern ECMA-262 5th specification splits arguments from local variables. But as of now, browsers still behave like described above. Try the examples to see.
Generally, it is a good practice not to modify arguments.
But I tried to run the above code, it output alert 1 twice instead of 1 and undefined.
http://javascript.info/tutorial/arguments
Could anyone please clarify that for me? Thanks
Upvotes: 0
Views: 66
Reputation: 1074168
As destroy pointed out, the reason you got the syntax error was that (the horror that is) Automatic Semicolon Insertion couldn't correct the code correctly and it was important to add the semicolon explicitly.
But to the meat of the question about the behavior of x
vs. the arguments
pseudo-array:
In loose mode (the default), there is a link between the named arguments and the arguments
pseudo-array. Here's a better demonstration of that link:
function foo(x) {
snippet.log(x); // "one"
snippet.log(arguments[0]); // also "one"
x = "two";
snippet.log(x); // "two"
snippet.log(arguments[0]); // also "two"
arguments[0] = "three";
snippet.log(x); // "three"
snippet.log(arguments[0]); // also "three"
}
foo("one");
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
See how arguments[0]
and x
are basically synonyms of each other.
The tutorial you refer to seems to believe that shifting the arguments
pseudo-array (removing the first entry) will make x
undefined
because arguments[0]
will be undefined
at that point. While that would be a reasonable interpretation of the link between the named x
and the arguments
pseudo-array, it's not true on Chrome's V8, Firefox's SpiderMonkey, IE11's JScript, or even IE8's much older JScript.
In strict mode, that link between the named arguments and the arguments
pseudo-array doesn't exist:
function foo(x) {
"use strict";
snippet.log(x); // "one"
snippet.log(arguments[0]); // also "one"
x = "two";
snippet.log(x); // "two"
snippet.log(arguments[0]); // "one" again, it wasn't changed
arguments[0] = "three";
snippet.log(x); // "two" again, it wasn't changed
snippet.log(arguments[0]); // "three"
}
foo("one");
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
In general, it's best to use strict mode, and to not rely on the link even in loose mode code.
Upvotes: 2
Reputation: 382122
You simply forgot the semicolon. Change
alert(x)
to
alert(x);
Be careful with semicolon : yes there is semicolon insertion making most of them optional but the rules are so hard you should really write most of them. Read more.
Regarding the modification of arguments
, you simply shouldn't. One of the reasons is that the behavior isn't the same when you're in strict mode, and it's not always easy to ensure you're not in strict mode because your code could have been concatenated with another one. The behavior mentioned in the bad and outdated tutorial you link to has been fixed since a long time.
Upvotes: 2