9
function Foo(f) {
   var f = f;    
}

在函数内部,变量f是局部的Foo(它具有函数范围),但是为什么f参数列表中的变量没有冲突?也许是因为它绑定在Foo.arguments对象内部?

在其他语言中,我们不能声明与局部变量同名的参数变量。

如何解决此名称歧义?或者,您如何f在该方法的后面引用这两个不同的变量中的每一个?

4

5 回答 5

12

JavaScript 做了几件显然不是很直观的事情——你感兴趣的事情叫做“提升”——JS 将 var 声明移动到函数的顶部,它们的唯一目的是将这个变量名保留为函数范围内的局部变量。有时,这会导致很多奇怪。如果变量名已被保留为局部变量(例如,它是一个参数),则 var 声明将被完全删除。

JS 的另一个不直观的部分是它如何处理参数变量和arguments对象(这有点特殊,如 Hippo 所示)。不过,这不一定是您感兴趣的 - 对于您的示例来说重要的是参数还将该变量名称声明为函数的本地变量。

所有这一切的结果是,当您拥有 avar f和参数 namef时,`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 页底部) 。

于 2009-03-19T16:16:05.303 回答
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);
于 2009-03-19T15:43:32.103 回答
2

一旦你声明了一个与旧变量同名的新变量,它就会覆盖它并且你不能同时引用这两个变量。

您应该更改参数或变量名称。

于 2009-03-19T15:36:46.863 回答
1

这里的函数变量 f 是 Foo 的本地变量(它具有函数范围),但参数列表中的变量 f 的命名方式与它不冲突的原因相同,可能是因为它绑定在 Foo.arguments 内部目的?

不,它不受参数的约束:参数只是位置参数值的数组,你不能从中得到“arguments.f”。

按名称传递给函数的参数成为局部变量。带有参数“f”的函数中的“var f”是隐含的。

当您在已经是本地的变量上声明 'var f' 时,什么也没有发生。您的代码与以下内容相同:

function Foo(f)
{
    f = f;
}

在其他语言中,我们不能声明与局部变量同名的参数变量。

在 JavaScript 中,只要在作用域块中使用了一次“var x”,那么在该块中对“x”的任何使用都是局部的。您可以愉快地在同一范围内一次又一次地在同一变量上声明“var”,但它什么也没做。

于 2009-03-19T16:50:06.517 回答
-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>

我在第 1 次和第 2 次警报中收到“Hello World”,在第三次收到“未定义”

于 2009-03-19T15:40:17.243 回答