有一段在线教程的代码
sayHi(1);
function sayHi(x); {
alert(x); // 1
[].shift.call(arguments);
alert(x); // undefined, no x any more :/
}
在教程中说:
修改参数的数组方法也会修改本地参数。
实际上,现代的ECMA-262第5规范将局部变量的参数分开。但截至目前,浏览器的行为仍然如上所述。试试这些例子。
通常,不修改参数是一种好习惯。
但我尝试运行上面的代码,它输出警报1两次而不是1和未定义。
http://javascript.info/tutorial/arguments
有人可以请我澄清一下吗?感谢
答案 0 :(得分:2)
你忘了分号。变化
alert(x)
到
alert(x);
小心分号:是的,有分号插入使其中大部分都是可选的,但是规则很难你应该写下大部分。 Read more
关于arguments
的修改,你根本就不应该这样做。其中一个原因是the behavior isn't the same when you're in strict mode,并且确保您不处于严格模式并不总是很容易,因为您的代码可能已经与另一个代码连接在一起。您链接到的错误和过时教程中提到的行为已经修复了很长时间。
答案 1 :(得分:2)
作为destroy pointed out,你得到语法错误的原因是(恐怖)自动分号插入无法正确纠正代码,显式添加分号很重要。
但是关于x
与arguments
伪阵列的行为的问题:
在松散模式(默认)下,命名参数和arguments
伪数组之间存在链接。以下是该链接的更好演示:
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>
了解arguments[0]
和x
基本上是彼此的同义词。
您引用的教程似乎相信转移 arguments
伪数组(删除第一个条目)会使x
undefined
因为{{ 1}}此时将arguments[0]
。虽然这对于命名的undefined
和x
伪阵列之间的链接是合理的解释,但在Chrome的V8,Firefox的SpiderMonkey,IE11的JScript,甚至是IE8更老的JScript上都不是这样。 / p>
在严格模式下,命名参数与arguments
伪数组之间的链接不存在:
arguments
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");
一般情况下,最好使用严格模式,即使在松散模式代码中也不要依赖链接。