2012-01-19 16 views
10

HTML:var x = x || "Val por defecto" no conseguir crear correctamente si x se define por encima de ella

<script type="text/javascript"> 
    var x = "overriden"; 
</script> 
<script src="myjs.js"></script> 

myjs.js:

$(document).ready(function(){ 
    var x = x || "default val"; 
    alert(x); // this alerts "default val" and not "overriden" 
}); 

Por alguna razón, x está terminando como "default val" y no "overriden", aunque inicialmente estoy estableciéndolo en "overriden" antes de incluir la referencia del script en myjs.js.

¿Alguna idea de por qué esto está sucediendo? Estoy intentando habilitar la página de hosting para establecer una anulación para una variable que se usa en un archivo js incluido; de lo contrario, use el valor predeterminado.

+0

Simplemente use 'var y = x || ... '. – kennytm

+0

quitando la palabra clave 'var' de la primera declaración? –

Respuesta

8

Lo que tienes después de la aplicación de elevación declaración de variables:

var x; 
x = 5; 

$(document).ready(function(){ 
    var x; 
    x = x || "default"; 
}); 

Se ve en el más cercano x y ve su valor es undefined que es un valor Falsy, por lo x consigue el sistema de "default".


que estaría bien si estuvieran en el mismo ámbito, debido a que las declaraciones siempre se alzan por encima de las asignaciones así:

var x = 5; 

var x = x || "default"; 

es en realidad

var x; 

x = 5; 
x = x || "default"; 

Esto fue sugerido que es completamente inútil:

$(document).ready(function(){ 
    x = x || "default"; 
}); 

Lanzará un ReferenceError si x no está definido.


Así que, o hacer la comprobación en el mismo ámbito o hacer algo como:

$(document).ready(function(){ 
    var x = window.x || "default"; 
}); 

válido de propiedad lee que no causen un ReferenceError pero sólo volver undefined lugar.

+0

marcando esto como respuesta porque varias otras respuestas sugirieron 'var y = x || "default" 'que mencionaste" Lanzará un ReferenceError si x no está definido. " –

3

Estás utilizando la palabra clave var en ambos lugares. Proveedores:

x = x || "default val"; 

https://developer.mozilla.org/en/JavaScript/Reference/Statements/var

Desde el enlace de arriba:

El ámbito de una variable declarada con var es la función de cerramiento o, para las variables declaradas fuera de una función, el alcance mundial (que está vinculado al objeto global).

1

Debido a que está declarando de nuevo una nueva var x dentro document.ready() que es otro ámbito que global. Prueba este

$(document).ready(function(){ 
    x = x || "default val"; 
    alert(x); // this will now alert "overriden" 
}); 
4

El var x en la función pasó a $(document).ready() se esconde el ámbito global x variable.

Si solo usa x = x || "default val";, entonces la variable global es eliminada. Sin embargo, realmente es una mala idea tener variables globales en absoluto.

1

x no está definido en el alcance de la función document ready.

var x está preparando la variable con el valor undefined, por lo que no la obtendrá del ámbito de la ventana.

Pruebe var x = x || window.x || "default val"; en su lugar.

+0

x dará error de referencia si no lo defino esa primera vez, fyi. –

1

Dado que lo tiene establecido con una var que no obtiene el objeto definido a nivel mundial desde el html. Intente eliminar la var y vea si obtiene un resultado diferente, o cambie la variable dentro de la función por una letra diferente.

Cuando usa var dentro de una función, el alcance de esa var es solo para la función. Como ha definido la variable x dos veces cuando realiza la comparación, está intentando usar la variable desde dentro de la función.

Si planea mantener la declaración var, deberá cambiar el nombre de la variable o la forma en que está llamando al x global al window.x. La otra opción es simplemente soltar la var de la función.

0

Usted está declarando var x en su función que crea almacenamiento local para x y oculta los valores anteriores.

Llámalo var y, o haz lo que karim79 sugiera.

+0

Realmente quiero aceptar esta, pero si hago var 'y = x || "default" ', entonces js arroja un error que dice que x no está definido. –

1

El x creado en esta línea:

var x = x || "default val"; 

... es local a la función que se define en (es decir, que shadows lo global x).

Al eliminar el var anterior, los nombres de x se harán referencia a la misma variable global, pero esto generalmente es una mala idea. Desde la página de Wikipedia relacionado anteriormente:

Esto puede llevar a confusión, ya que puede ser claro qué variables usos posteriores del nombre de la variable se refieren a la sombra.

0

Su var x en el segundo es local para esa función, y no es lo mismo que window.x (que es lo que ha definido en el primer bloque).

0

la palabra clave var significa que acaba de crear una variable local. Así que básicamente lo que está sucediendo es que:

  1. Usted declara (en su primer bloque) x como "invalidado"

memoria:

x -> "overriden" 
  1. se establece la devolución de llamada al documento .ready

Memoria:

x -> "overriden" 

(después de que el documento está cargado) 3. ejecuta su función anónima, con inicialización x var

memoria:

x->"overriden" 
[IN SCOPE] 
anonymous_function.x -> "default_value" 
[/SCOPE] 

"Pero espera", es posible que digamos, "el código que escribí es var x= x || "default var", entonces ¿qué debería pasar es local_x=global_x || "default value, derecho?

Desafortunadamente, Javascript no funciona de esa manera. En Javascript, tenemos el alcance de la función, en lugar del ámbito de bloque más utilizado. Así que cuando usted escribe:

f=function(){ 
    var x=y || "default value"; 
    var y=3; 
    alert(x); 
} 

lo que va a ser interpretado en javascript es:

f=function(){ 
    var x; 
    var y; 
    x=y || "default value"; 
    y=3; 
    alert(x); 
} 

lo que la ejecución y=10; f(); le dará "valor por defecto" en el símbolo.


Así que quitarse el var trabajará para arreglar el problema aquí, pero sólo recuerda, en general, que todas sus declaraciones de variables se hacen "al principio" de una función, por lo que el alcance se cambia inmediatamente al entrar en una función .

Cuestiones relacionadas