Huibin Zhang
Huibin Zhang

Reputation: 1110

javascript example code cannot run

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

Answers (2)

T.J. Crowder
T.J. Crowder

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

Denys S&#233;guret
Denys S&#233;guret

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

Related Questions