function Foo(f) {
var f = f;
}
在函数内部,变量f
是Foo
的本地(它有一个函数作用域),但为什么参数列表中的变量f
没有冲突?也许是因为它绑定在Foo.arguments
对象中?
在其他语言中,我们不能声明一个与局部变量同名的参数变量。
这个名称歧义是如何解决的?或者,如何在方法的后面引用两个不同的f
变量中的每一个?
答案 0 :(得分:12)
JavaScript做了一些显然不直观的事情 - 你感兴趣的事情被称为“提升” - JS将var声明移动到函数的顶部,它们的唯一目的是保留这个变量将name命名为函数范围内的局部变量。有时,这会导致lots of weirdness。如果变量名已经被保留为局部变量(例如它是一个参数),var声明将被完全删除。
JS的另一个不直观的部分是它如何处理参数变量和arguments
对象(这有点特殊,正如Hippo所示)。但这并不一定是你感兴趣的 - 对你的例子来说重要的是参数还声明变量名称是函数的本地名称。
所有这一切的结果是,当你有一个var f
以及一个参数名f
时,`var f'会被删除,你的例子相当于:
function Foo(f) {
f = f;
}
你可以在Hippo的例子中看到这个,因为:
function foo(f) {
console.log(f); // --> 11
console.log(arguments); // --> array [11]
var f = 10;
console.log(f); // --> 10
console.log(arguments); // --> [10] (!!!)
}
相当于:
function foo(f) {
var f;
console.log(f); // --> 11
console.log(arguments); // --> array [11]
f = 10;
console.log(f); // --> 10
console.log(arguments); // --> [10] (!!!)
}
相当于:
function foo(f) {
console.log(f); // --> 11
console.log(arguments); // --> array [11]
f = 10;
console.log(f); // --> 10
console.log(arguments); // --> [10] (!!!)
}
有关详细信息,请阅读JS规范ECMA-262中 10.1.3 - 变量实例化(第37页底部)部分。
答案 1 :(得分:6)
除了重命名其中一个或将值存储在另一个变量中之外,无法解决此问题。
function foo(f) {
console.log(f); // --> 11
console.log(arguments); // --> array [11]
var f=10;
console.log(f); // --> 10
console.log(arguments); //even this is now array [10]
}
foo(11);
答案 2 :(得分:2)
一旦声明一个与旧名称相同的新变量,它就会覆盖它,你不能同时引用它们。
您应该更改参数或变量名称。
答案 3 :(得分:1)
这里的函数变量f是Foo的本地(它有一个函数作用域)但是参数列表中的变量f以相同的方式命名,因为它不在冲突中,因为它绑定在Foo.arguments对象?
不,它没有绑定参数:arguments只是一个位置参数值数组,你不能从中获取'arguments.f'。
按名称传递给函数的参数成为局部变量。参数'f'的函数中的“var f”是隐式的。
当您对已经是本地的变量声明'var f'时,没有任何反应。您的代码与:
相同function Foo(f)
{
f = f;
}
在其他语言中,我们不能声明一个与局部变量同名的参数变量。
在JavaScript中,只要在作用域块中使用“var x”,该块中的“x”的任何使用都是本地的。你可以一次又一次地在同一个范围内对同一个变量声明'var',但它没有做任何事情。
答案 4 :(得分:-1)
在firefox中,我注意到声明新变量并没有造成任何伤害,这几乎就好像这个版本不适用于此
<script type="text/javascript">
function saymessage(f) {
alert(f);
var f = f;
alert(f);
alert(this.f);
}
</script>
</head>
<body >
<!-- Insert Body Here -->
<button id='link' textToShow="Hidden message text" onclick="saymessage('Hello World')">Click me </button>
</body>
我在第一和第二个警报上得到“Hello World”,在第三个
上得到“undefined”