pasar - retornar valor de una funcion javascript
¿Por qué no se sobrescribe el argumento de la función al crear una variable con el mismo nombre dentro de la función? (4)
var a = ''why is this not undefined?'';
function checkScope(a) {
var a;
console.log(a);
}
checkScope(a);
Javascript es el lenguaje de alcance funcional, ¿verdad? Cuando declaro una nueva variable justo dentro de la función que usa el mismo nombre que el argumento funcional, ¿por qué la variable recién definida sigue teniendo los mismos datos que el argumento?
Pensé que debería estar indefinido?
está pasando la variable a a la función check como parámetro.
function checkScope(a) {
dentro de la función está intentando declarar nuevamente var a,
var a;
Ambos están dentro del mismo ámbito, ¿verdad? es decir, ambos dentro de la función check ();
Y de acuerdo con los docs , esa var a
dentro de la función es la misma variable que pasaste como parámetro y solo la estás utilizando antes de la declaración ... puedes hacerlo con JS
Así que el código que has escrito es equivalente a
var a = ''why is this not undefined?'';
function checkScope(a) {
console.log(a);
}
checkScope(a);
es decir, la var a es simplemente ignorada.
Y lo que esperas que var a debería devolver no definido entonces el código sería así
var a = ''why is this not undefined?'';
function checkScope() {
var a
console.log(a);
}
checkScope();
Esta vez no estamos pasando el parámetro a a la función y se crea una nueva variable var a
dentro del alcance de la función, por lo que se convierte en indefinido
El parámetro todavía está definido dentro de la función, debido a la var a;
se ignora cuando la variable ya está definida dentro del mismo ámbito.
Una declaración como var a;
no significa que la variable se crea en ese punto en el código. Todas las declaraciones de variables se colocan en la parte superior del alcance, por lo que puede volver a declararlas tantas veces como desee en el alcance, y aún se crean una sola vez.
Si una declaración tiene una asignación, como var a = 2;
, la asignación ocurre cuando la declaración está en el código, independientemente de si la declaración se ignora o no.
Ejemplo:
function check(a) {
// both a and b exist here
document.write(''a = '' + a + '', b = '' + b + ''<br>'');
var b = 1;
document.write(''a = '' + a + '', b = '' + b + ''<br>'');
var a = 2; // not recreated, but assigned
document.write(''a = '' + a + '', b = '' + b + ''<br>'');
}
check(42);
Porque JavaScript ignora las redeclaraciones de variables. Sin embargo, si tuvieras esto en su lugar:
var a = ''why is this not undefined?'';
function checkScope(a) {
var a = ''foo'';
console.log(a);
}
checkScope(a);
El valor de a
sería sobreescrito. Porque var a = ''foo'';
está compuesto por una declaración de variable ( var a;
) y una asignación de valor ( a = ''foo'';
);
Este comportamiento se describe en los docs .
var a;
es en realidad una declaración de declaración variable. Cuando se define la función, todas las variables declaradas en ella se procesan antes de la ejecución del código, por lo que puede usar las variables incluso antes de que se ejecute la línea de declaración real en tiempo de ejecución. Esto se llama var
elevación . Entonces, no importa cuántas veces declare una variable, la variable en realidad se declara solo una vez.
En su caso, ha definido a
como uno de los parámetros para la función, que está dentro del alcance de la función actual. Y luego estás declarando una variable con el mismo nombre. Como a
ya está declarado en la función, como uno de los parámetros, la var a;
La declaración será ignorada.
Es por eso que estás recibiendo, why is this not undefined?
en la consola
En lugar de var a;
, digamos que tienes var a = 1;
En este caso, la variable ya está declarada, pero la expresión de asignación se evaluará en tiempo de ejecución y el valor 1
se asignará a a
. Por lo tanto, la console.log
se imprimirá 1
.
Este comportamiento se explica en la especificación ECMA Script 5.1, en la sección 10.5 Declaración de creación de instancias ,
Si el código es un código de función, entonces
a. Deje que func sea la función cuyo [[Call]] método interno inició la ejecución del código . Deje que los nombres sean el valor de la propiedad interna [[FormalParameters]] de la función.
segundo. Sea argCount el número de elementos en args.
do. Sea n el número 0.
re. Para cada StrName argName en los nombres , en orden de lista
yo. Sea n el valor actual de n más 1.
ii. Si n es mayor que argCount , sea v no estar definido de lo contrario, v sea el valor del elemento n ''th de args .
iii. Deje que argAlreadyDeclared sea el resultado de llamar al método concreto HasBinding de env pasando a argName como argumento.
iv. Si argAlreadyDeclared es falso, llame al método concreto CreateMutableBinding de env pasando argName como el argumento.
v. Llame al método concreto SetMutableBinding de env , pasando argName , v y estricto como los argumentos.
....
Para cada VariableDeclaration y VariableDeclarationNoIn d en el código , en el orden del texto fuente
a. Sea dn el identificador en d .
segundo. Deje que varAlreadyDeclared sea el resultado de llamar al método concreto HasBinding de env pasando dn como argumento.
do. Si varAlreadyDeclared es falso, entonces
yo. Llame al método concreto CreateMutableBinding de env pasando dn y configurableBindings como argumentos.
ii. Llame al método concreto SetMutableBinding de env , pasando dn , undefined y estricto como los argumentos.
Como vemos en la especificación, los argumentos y las variables declaradas en la función, todos están realmente definidos en el entorno de ejecución correspondiente a la función en la que están definidos. Entonces, si los argumentos y las variables tienen el mismo nombre, la variable en realidad se define solo una vez y la segunda declaración se ignora.