2009-03-19 25 views
9
function Foo(f) { 
    var f = f;  
} 

Aquí dentro de la función, variables f es local a la Foo (tiene un ámbito de función), pero ¿por qué es la variable f en la lista de argumentos no en conflicto? Tal vez porque está dentro del objeto Foo.arguments?argumentos de la función

En otros idiomas no podemos declarar una variable de argumento con el mismo nombre que una variable local.

¿Cómo se resuelve la ambigüedad de este nombre? O bien, ¿cómo hace referencia a cada una de las dos variables distintas f más adelante en el método?

+0

¿Y cuál es la pregunta? –

+0

La pregunta está implícita: cómo se resuelve el nombre de la ambigüedad o cómo se hace referencia a cada una de las dos variables "f" distintas más adelante en el método. –

Respuesta

12

JavaScript hace un par de cosas que no son, obviamente, intuitiva - el que usted está interesado en que se denomina "elevación" - JS mueve declaraciones var a la parte superior de una función, donde sirven el único propósito de reservar este nombre de variable como una variable local en el alcance de la función. A veces, esto lleva a lots of weirdness. Si el nombre de la variable ya está reservado como una variable local (por ejemplo, es un argumento), la declaración var se descarta por completo.

Otra parte no intuitiva de JS es cómo se trata con las variables de argumento y el objeto arguments (que son un poco especiales, como mostró Hippo). Sin embargo, eso no es necesariamente lo que le interesa, lo que es importante para su ejemplo es que los argumentos también declaran ese nombre de variable como local para la función.

El resultado de todo esto es que cuando se tiene un var f, así como un nombre de argumento f, el `var f' se cae, y su ejemplo es equivalente a:

function Foo(f) { 
    f = f; 
} 

Esto se puede ver en el ejemplo de Hipona, porque:

function foo(f) { 
    console.log(f); // --> 11 
    console.log(arguments); // --> array [11] 
    var f = 10; 
    console.log(f); // --> 10 
    console.log(arguments); // --> [10] (!!!) 
} 

es equivalente a:

function foo(f) { 
    var f; 
    console.log(f); // --> 11 
    console.log(arguments); // --> array [11] 
    f = 10; 
    console.log(f); // --> 10 
    console.log(arguments); // --> [10] (!!!) 
} 

es equivalente a:

function foo(f) { 
    console.log(f); // --> 11 
    console.log(arguments); // --> array [11] 
    f = 10; 
    console.log(f); // --> 10 
    console.log(arguments); // --> [10] (!!!) 
} 

Para más detalles, leer la sección 10.1.3 - instanciación variable (parte inferior de la página 37) en ECMA-262, la especificación JS.

+1

"hositing" se debe deletrear "hoisting" –

+0

¡Solucionado, gracias! –

2

Una vez que declara una nueva variable con el mismo nombre de una anterior, la reemplaza y no puede hacer referencia a ambas al mismo tiempo.

Debe cambiar el parámetro o el nombre de la variable.

-1

en Firefox me di cuenta de que la declaración de la nueva variable no hizo ningún daño es casi como si el stament no estaba allí para este

<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> 

llegué "Hello World" en la 1ª y 2ª alertas y "indefinido" en el tercero

+1

sí porque está vinculado al objeto ventana en ese contexto de función y no está definido porque no existe ninguna variable declarada como window.f = ... – xdevel2000

6

No hay forma de resolver este problema, excepto cambiarle el nombre a uno de ellos o almacenar el valor en otra variable.

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); 
+1

en realidad eso es incorrecto: D la primera vez que inicie sesión (f) producirá undefined, ya que js spec eleva todas las declaraciones de var al comienzo de la función (la asignación permanece en la misma posición) – olliej

+0

@olliej: en este caso, 'f' ya está definido localmente a través del primer argumento, y de hecho se ha establecido a '11' antes de que se ejecute la función debido al valor pasado. – pimvdb

1

aquí dentro de la variable de función f es local para el Foo (tiene un alcance de función) pero la variable f en la lista de argumentos que se nombra de la misma manera por la que no está en conflicto puede ser porque es atada dentro del objeto Foo.arguments?

No, no está vinculado a argumentos: argumentos es solo una matriz de valores de argumento posicional, no se puede obtener 'arguments.f' fuera de ella.

Los argumentos pasados ​​a una función por nombre se convierten en variables locales. La "var f" en una función con el argumento 'f' es implícita.

Cuando declara 'var f' en una variable que ya es local, no pasa nada. Su código es idéntico a:

function Foo(f) 
{ 
    f = f; 
} 

En otros idiomas que no podemos declarar una variable de discusión con el mismo nombre que una variable local.

En JavaScript, siempre que haya un uso de "var x" en un bloque de alcance, cualquier uso de 'x' en ese bloque es local. Puede declarar felizmente 'var' en la misma variable en el mismo ámbito una y otra vez, pero no hace nada.

+1

puede ser el alcance de la función ... JS no tiene un bloque de alcance – xdevel2000

Cuestiones relacionadas