2009-04-02 16 views
42

me siento como si tratara de hacer algo súper simple, pero solo ser estúpido al respecto.javascript: defina una variable si no existe

todo lo que quiero hacer es ver si una variable se ha establecido previamente, y si no lo tiene, configurarlo con un valor predeterminado

.... Este es un ejemplo:

if(!embed_BackgroundColor) { 
    var embed_BackgroundColor; 
    embed_BackgroundColor = "#F4F4F4"; 
} 

así, una vez dejas de reírte de mi código ... ¿POR QUÉ está sobreescribiendo la variable pase lo que pase?

Por favor, guarde mis nervios;)

Respuesta

52
if (typeof variable === 'undefined') { 
    // variable is undefined 
    // eg: 
    // var variable = "someValue"; 
} 
+0

el problema es que no importa lo que la variable var = // "someValue" es sobrescribir el valor predefinido que existiera – johnnietheblack

+0

es que en realidad, tres = s? (No sé) – jedierikb

+3

No estoy seguro de por qué esto es aceptado. Parece usar el código anterior (con la variable 'var variable = "someValue"; 'la línea sin comentario da como resultado' variable' siempre siendo igual a "algúnValor" incluso si ya estaba definido. –

0

creo que su código publicado debería funcionar. A menos que su valor original sea 0.

El problema está en otro lugar.

Supongo que definió 'embed_BackgroundColor' fuera del alcance de su código. Y cuando ejecuta su código, esa variable no está definida en el alcance de su código, y se le asignará el valor predeterminado.

Aquí se muestra un ejemplo:

var embed_BackgroundColor = "#FF0000"; 

(function(){ 
    if(!embed_BackgroundColor) { 
    var embed_BackgroundColor; 
    embed_BackgroundColor = "#F4F4F4"; 
    } 
    alert(embed_BackgroundColor); // will give you #F4F4F4 
})(); 

alert(embed_BackgroundColor); // will give you #FF0000; 
0

prefiero una solución general en el estilo de PHP-como:

function isset(x) { return typeof(x)!='undefined'; }

+0

esto no funcionará. Te dará un error de referencia: [x] no está definido. – KooiInc

+0

Funciona, pero debes recordar que isset (obj.arr [x]) no funcionará si no verifica primero isset (obj) y luego isset (obj.arr). – Thinker

42

que sería una práctica de codificación bien en este caso utilizar el ternario operador. Además, no necesita tener tres signos iguales al comparar con typeof. Esta es la solución más concisa:

b = typeof(b) == 'undefined' ? 0 : b; 

Espero que esto le ahorrará algo de tiempo.

+1

Similar al comentario sobre la respuesta de 'calmbird' (debajo ... tal vez), parece que b se está reasignando a sí mismo cuando está definido. Parece que podría ser malo-ish (no terrible) en un ciclo. De nuevo, yo no No sé cómo el intérprete lidiará con esto exactamente, pero parece que será una reasignación innecesaria. – dylnmc

+5

Creo que debe usar '===' en lugar de '==' –

+0

Esta debería ser la respuesta aceptada, la respuesta con el mayor número de votos no siempre funcionará –

1

Si embed_BackgroundColor es un parámetro en una función que no consiguió pasar, se puede establecer un valor predeterminado con

embed_BackgroundColor ? embedBackgroundColor : embed_BackgroundColor = "#F4F4F4"; 

Ejemplo de función completa

function colorFunctionThing(embed_BackgroundColor) { 
    embed_BackgroundColor ? embed_BackgroundColor : embed_BackgroundColor = "#F4F4F4"; 
    console.log(embed_BackgroundColor); 
}; 
colorFunctionThing(); 

salidas

#F4F4F4 

No es exactamente lo que estabas buscando, pero aún así es muy bueno saberlo.

25

Para responder realmente a su pregunta de POR QUÉ esto está sucediendo, solo han pasado un poco más de dos años y un mes: D, es por variable hoisting.

Básicamente, hay una fase antes de ejecutar código en el ámbito global o dentro de una función donde el código es escaneado para todos los var y function declaraciones (que no debe confundirse con la función expresiones, pero eso es otra historia).
Todas estas variables y funciones se declaran dentro del alcance actual, y solo después ejecuta realmente el código.

Esto ocurre independientemente de su posición en el código, con ámbitos correspondientes a cuerpos de funciones, no bloques de instrucciones. Y lo que lo hace aún más contra-intuitivo, incluso si establece un valor inicial para las variables en sus declaraciones, they will still remain "empty" until the declaration is reached again in normal execution flow.

Así que cuando se escribe:

if(!embed_BackgroundColor) { 
    var embed_BackgroundColor; 
    embed_BackgroundColor = "#F4F4F4"; 
} 

lo que en realidad sucede es lo siguiente:

  1. Código se analizan en busca de declaraciones var. embed_BackgroundColor se declara dentro de este alcance, independientemente de si ya fue declarado o no. Su valor inicial no está definido.

  2. Comienza la ejecución del código. Se ejecuta la instrucción if. La variable es declarada, pero su valor no está definido, por lo que la condición es verdadera. Usar typeof no lo ayudaría a distinguir aquí entre una variable no declarada y una declarada pero no establecida aún. No hace ninguna diferencia de todos modos.

  3. La declaración var se alcanza por el flujo normal del código. Si le hubieras dado a la variable un valor inicial, se habría establecido ahora. En este caso, no pasa nada.

  4. embed_BackgroundColor se establece en el valor "#F4F4F4".

Así, la línea de fondo es: se puede usar typeof variable == 'undefined' como se ve en las otras respuestas, o incluso claro como el que estaba utilizando al principio, pero no utiliza var o que va a arruinar todo 'variable!'.

+0

¿Está realmente en estado de ser declarado pero se evalúa como "indefinido"? ¡Pensé que el propósito de indefinido era para cosas que no están declaradas! (es decir, no definido). ¿Quieres decir nulo? – Moss

+0

@Moss No, realmente es 'undefined'. Es el valor predeterminado para las variables no inicializadas en JS (sin inicializar me refiero a "sin un valor asignado a ellas"). Solo pruébalo en Firebug o lo que sea: 'typeof blah' evaluará la cadena' 'undefined''. – Zecc

+2

Alguien por favor cambie esto en la respuesta correcta ... – Merc

10

prefiero esta sintaxis:

embed_BackgroundColor = embed_BackgroundColor || "#F4F4F4"

no puede conseguir mucho más simple que eso! Y parece funcionar incluso si ha sido variado.

+5

'' 'ReferenceError: embed_BackgroundColor no está definido''' Necesidad de definir' '' var embed_BackgroundColor '' 'first –

1

Sigo el blog de Chris West y vi que publicó una manera muy buena en http://gotochriswest.com/blog/2012/07/02/javascript-define-if-undefined/.

Básicamente, usted tiene la definición de la función define y luego utilizar de esta manera:

define("embed_BackgroundColor", "#F4F4F4"); 

El código anterior definirá enbed_BackgroundColor en el contexto global, si no está ya definido. El ejemplo que utiliza Chris es un poco más útil y es el siguiente:

alert("jStuff is " + (typeof jStuff == "undefined" ? "un" : "") + "defined."); 

define("jStuff.alert", function(msg) { 
    alert(msg); 
    return msg; 
}); 

alert("jStuff is " + (typeof jStuff == "undefined" ? "un" : "") + "defined."); 

var str = jStuff.alert("Show and save this message."); 
  • la primera declaración de alerta se mostrará, "jStuff no está definido."
  • Aparecerá la segunda declaración de alerta, "jStuff está definido".
  • La declaración de alerta final mostrará la alerta especificada y luego esa cadena se almacenará en la variable str.
66

Pro estilo:

var SomeVar = SomeVar || 'Default Value'; 
+1

: \ ¿Esto no reasigna' SomeVar' a sí mismo? De hecho, se ve como un estilo "pro", pero, de hecho, parece estar un poco optimizado (especialmente para un ciclo for/while). Me quedaría con un if. Sin embargo, podría estar equivocado y el intérprete podría reconocer que no necesita almacenar una 'var' de nuevo en * sí mismo *. – dylnmc

+2

Esta es la respuesta "correcta". – codebreaker

+7

Una palabra de advertencia: si 'SomeVar' puede ser un valor de falso-y, esto fallará. Cosas como '''', 'false', y' 0' dispararán '||' y establecerán el valor predeterminado Si desea que 'SomeVar' pueda ser valores 'false-y', entonces use un ternario, como en @Jhuni answer (pero con la palabra clave var como en este). También estoy de acuerdo con @dylnmc, esto da como resultado una reasignación inútil. @Paolo Berantino tiene lo que creo que es la respuesta "correcta". Personalmente estoy totalmente en desacuerdo con que "pequeño y compacto" es necesariamente "estilo profesional". Ya no usamos tarjetas perforadas, y los minificadores js ecualizan el resto. – Fodagus

9

Si se trata de una variable global, me gusta hacer:

var defineMe = window.defineMe || 'I will define you now'; 

Es importante utilizar el espacio de nombres de ventana, ya que hace referencia a variables no definidas causará muy malas errores, pero hacer referencia a propiedades indefinidas no lo hará.

0

Debido a su bloque if se ejecutará si es embed_BackgroundColorfalse, 0, "", null, undefined o NaN.

Pero embed_BackgroundColor no se deben sobrescribir si ya se ha asignado a otro cadena no vacía ... O al menos, no lo hace en mi final.

Quizás es un caso de ámbitos contradictorios, como ha señalado Aaron Qian.

0

La mejor opción:

if (typeof someVar === 'undefined') someVar = someValue; 
Cuestiones relacionadas