¿Puedo establecer variables como indefinidas o pasar indefinidas como argumento?

304

Estoy un poco confundido sobre los valores undefinedy JavaScript null.

¿Qué hace if (!testvar)realmente? Qué es la prueba undefinedy nullo simplemente undefined?

Una vez que se define una variable, ¿puedo volver a undefinedborrarla (por lo tanto, eliminar la variable)?

¿Puedo pasar undefinedcomo parámetro? P.ej:

function test(var1, var2, var3) {

}

test("value1", undefined, "value2");
AJ
fuente

Respuestas:

514

Estoy un poco confundido acerca de Javascript indefinido y nulo.

No te confundas null. Por lo general, tiene sentido y se comporta de manera similar a los conceptos de otros lenguajes de script de los objetos 'nulo', 'nulo' o 'Ninguno' fuera de banda.

undefined, por otro lado, es una peculiaridad extraña de JavaScript. Es un objeto singleton que representa valores fuera de banda, esencialmente un segundo similar pero diferente null. Surge:

  1. Cuando llama a una función con menos argumentos que la lista de argumentos en las functionlistas de instrucciones, los argumentos no pasados ​​se establecen en undefined. Puede probar eso con, por ejemplo:

    function dosomething(arg1, arg2) {
        if (arg2===undefined)
        arg2= DEFAULT_VALUE_FOR_ARG2;
        ...
    }

    Con este método no se puede distinguir entre dosomething(1)y dosomething(1, undefined); arg2será el mismo valor en ambos. Si necesita distinguir la diferencia que puede ver arguments.length, pero hacer argumentos opcionales como ese generalmente no es muy legible.

  2. Cuando una función no tiene return value;, regresa undefined. En general, no es necesario usar un resultado de devolución de este tipo.

  3. Cuando declara una variable al tener una var adeclaración en un bloque, pero aún no le ha asignado un valor, lo es undefined. De nuevo, en realidad nunca deberías necesitar confiar en eso.

  4. El typeofoperador espeluznante regresa 'undefined'cuando su operando es una variable simple que no existe, en lugar de arrojar un error como sucedería normalmente si intentara referirse a él. (También puede darle una variable simple entre paréntesis, pero no una expresión completa que involucre una variable no existente). Tampoco es muy útil para eso.

  5. Este es el controvertido. Cuando accede a una propiedad de un objeto que no existe, no obtiene inmediatamente un error como en cualquier otro idioma. En cambio, obtienes un undefinedobjeto. (Y luego, cuando intente usar ese undefinedobjeto más adelante en el script, saldrá mal de una manera extraña que es mucho más difícil de rastrear que si JavaScript hubiera arrojado un error de inmediato).

    Esto se usa a menudo para verificar la existencia de propiedades:

    if (o.prop!==undefined) // or often as truthiness test, if (o.prop)
       ...do something...

    Sin embargo, porque puede asignar undefinedcomo cualquier otro valor:

    o.prop= undefined;

    eso no detecta realmente si la propiedad está allí de manera confiable. Es mejor usar el inoperador, que no estaba en la versión original de Netscape de JavaScript, pero ahora está disponible en todas partes:

    if ('prop' in o)
        ...

En resumen, undefinedes un desastre específico de JavaScript, que confunde a todos. Además de los argumentos de funciones opcionales, donde JS no tiene otro mecanismo más elegante, undefineddebe evitarse. Nunca debería haber sido parte del lenguaje; nullhabría funcionado bien para (2) y (3), y (4) es un error que solo existe porque al principio JavaScript no tenía excepciones.

¿Qué hace if (!testvar)realmente? ¿Prueba para indefinido y nulo o simplemente indefinido?

Tal 'truthiness' prueba comprueba contra false, undefined, null, 0, NaNy cadenas vacías. Pero en este caso, sí, es realmente undefinedlo que le preocupa. En mi opinión, debería ser más explícito al respecto y decir if (testvar!==undefined).

una vez que se define una variable, ¿puedo volver a borrarla a indefinida (por lo tanto, eliminar la variable)?

Ciertamente puede asignarle undefined, pero eso no eliminará la variable. Solo el delete object.propertyoperador realmente elimina las cosas.

deleteestá realmente destinado a propiedades en lugar de variables como tales. Los navegadores le permitirán salirse con la suya delete variable, pero no es una buena idea y no funcionará en el modo estricto de ECMAScript Fifth Edition. Si desea liberar una referencia a algo para que se pueda recolectar basura, sería más habitual decirlo variable= null.

¿Puedo pasar indefinido como parámetro?

Si.

bobince
fuente
10
Qué respuesta tan fantástica. Acabo de reprobar la prueba de JavaScript: perfectionkills.com/javascript-quiz Más tarde, ¡volveré a leer su respuesta e intentaré la prueba nuevamente!
Drilldrick
1
fijo, ta. (Tiendo a no preocuparme demasiado por la reasignación, ya que hay tantas cosas que un guión podría redefinir para estropear todo que el caso general es imposible de resolver.)
bobince
2
@bobince undefinedes un objeto singleton? ¿Qué quieres decir? Es un valor primitivo, y no un objeto.
Šime Vidas el
2
@Hortitude: Ese es el punto (4). Generalmente no lo haría typeof foo=='undefined'; tiende a usarse para (4a) rastreo global, en cuyo caso preferiría ser explícito y decir 'foo' in window, o (4b) probar contra el undefinedvalor en sí, en cuyo caso preferiría ser legible y decir foo===undefined. En teoría, las pruebas en typeofcontra 'undefined'podrían tener un caso de uso que otras construcciones no podrían proporcionar: la detección de la existencia de variables locales. Sin embargo, en realidad casi siempre sabes qué variables se declaran locales.
bobince
44
Una advertencia con el n. ° 2, generalmente una función sin returninstrucción devuelve undefined, pero si la función es un constructor (invocado con el newoperador) devolverá el nuevo objeto (el valor thisdentro del constructor) a pesar de no tener una returninstrucción. console.log((function (){}()));vuelve undefined. console.log((new function (){}()));devuelve un objeto
Código inútil el
18

No puede (¿no debería?) Definir nada como indefinido, ya que la variable ya no estaría indefinida, simplemente la definió como algo.

No puede (¿no debería?) Pasar undefineda una función. Si desea pasar un valor vacío, use nullen su lugar.

La declaración if(!testvar)verifica los valores booleanos de verdadero / falso, este en particular prueba si se testvarevalúa como false. Por definición, nully undefinedno debe evaluarse ni como trueni false, pero JavaScript evalúa nullcomo false, y da un error si intenta evaluar una variable indefinida.

Para probar undefinedo nullutilizar correctamente estos:

if(typeof(testvar) === "undefined") { ... }

if(testvar === null) { ... }
Tatu Ulmanen
fuente
1
El triple igual también verifica el tipo, por lo que no se realiza ninguna coerción de tipo. Douglas Crockford desaconseja el uso de operadores de coerción de tipos ( ==y !=).
Drilldrick
3
Puede definir algo como indefinido. var a= undefined. Puedes pasar fn(undefined). Si desea encontrar la diferencia entre una propiedad indefinida pde un objeto oy una propiedad pque se ha definido y establecido en undefined, debe usar el 'p' in ooperador.
bobince
1
¿Hay alguna razón por la que uno no deba probar en testvar === undefinedlugar de ser el más complicado typeof(testvar) === "undefined"?
ddaa
44
Hay otra buena razón para usar una typeofprueba para variables indefinidas: a diferencia null, undefinedes simplemente una propiedad del objeto global y puede redefinirse. Solo toma un estilo de codificación particular y un signo igual que falta y undefinedse cambia en silencio:if (undefined = someVar) {...}
Tim Down
1
@IanGrainger: ECMAScript 5 (implementado en las versiones actuales de todos los navegadores) en su mayoría corrige esto al hacer undefineduna propiedad inmutable del objeto global, por lo que es más seguro de lo que solía ser. Sin embargo, todavía es posible definir una variable mutable llamada undefineddentro de una función, por lo que el problema no ha desaparecido por completo.
Tim Down
13

La diferencia básica es eso undefinedy nullrepresentan conceptos diferentes.

Si solo nullestuviera disponible, no podrá determinar si nullse configuró intencionalmente como el valor o si el valor aún no se ha establecido a menos que haya utilizado la captura de errores engorrosos: por ejemplo

var a;

a == null; // This is true
a == undefined; // This is true;
a === undefined; // This is true;

Sin embargo, si se establece el valor intencionadamente a null, la igualdad estricta con la undefinedfalla, lo que le permite diferenciar entre nully undefinedvalores:

var b = null;
b == null; // This is true
b == undefined; // This is true;
b === undefined; // This is false;

Echa un vistazo a la referencia aquí en lugar de confiar en que la gente dice despectivamente basura como "En resumen, indefinido es un desastre específico de JavaScript, que confunde a todos". El hecho de que estés confundido no significa que sea un desastre.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined

También este comportamiento no es específico de JavaScript y que completa el concepto generalizado de que un resultado booleano puede ser true, falsey desconocido ( null), no tiene valor ( undefined), o algo salió mal ( error).

http://en.wikipedia.org/wiki/Undefined_value

Todd
fuente
Y aún nullasí hubiera funcionado bien. a == nulles trueporque la coacción de tipo Javascript.
sleepwalkerfx
11

La mejor manera de verificar los valores nulos es

if ( testVar !== null )
{
    // do action here
}

y para indefinido

if ( testVar !== undefined )
{
    // do action here
}

Puede asignar una variable con indefinido.

testVar = undefined;
//typeof(testVar) will be equal to undefined.
rahul
fuente
1
La mejor manera de verificar valores nulos es usar !==, no!=
MBO
6

SÍ, puede, porque indefinido se define como indefinido.

console.log(
   /*global.*/undefined === window['undefined'] &&
   /*global.*/undefined === (function(){})() &&
   window['undefined']  === (function(){})()
) //true

Tu caso:

test("value1", undefined, "value2")

También puede crear su propia variable indefinida:

Object.defineProperty(this, 'u', {value : undefined});
console.log(u); //undefined

fuente
5

Para responder a su primera pregunta, el operador no ( !) forzará lo que sea que se le dé a un valor booleano. Así null, 0, false, NaNy ""(cadena vacía) le aparecerá toda falsa.

Drilldrick
fuente
Y también cadena vacía y NaN (no es un número)
MBO
undefinedno aparecerá como false, arrojará un error 'no está definido'.
Tatu Ulmanen
Tatu Ulmanen: no es cierto. if (undefined) {/* Do stuff*/}no dará un error, ya que undefinedexiste como una propiedad del objeto global. Lo que dará un error es algo asíif (someUndeclaredVariable) {/* Do stuff*/}
Tim Down
2

JavaScript, cómo configurar una variable como indefinida en la línea de comandos:

Establezca una variable como indefinida en el jsterminal de línea de comandos de JavaScript que viene con Java en Ubuntu 12.10.

el@defiant ~ $ js

js> typeof boo
"undefined"

js> boo
typein:2: ReferenceError: boo is not defined

js> boo=5
5

js> typeof boo
"number"

js> delete(boo)
true

js> typeof boo
"undefined"

js> boo
typein:7: ReferenceError: boo is not defined

Si configura una variable como indefinida en un javascript:

Pon esto en myjs.html:

<html>
<body>
    <script type="text/JavaScript">
        document.write("aliens: " + aliens);
        document.write("typeof aliens: " + (typeof aliens));
        var aliens = "scramble the nimitz";
        document.write("found some aliens: " + (typeof aliens));
        document.write("not sayings its aliens but... " + aliens);
        aliens = undefined;
        document.write("aliens deleted");
        document.write("typeof aliens: " + (typeof aliens));
        document.write("you sure they are gone? " + aliens);
    </script>
</body>
</html>

Imprime esto:

aliens: undefined
typeof aliens: undefined
found some aliens: string
not sayings its aliens but... scramble the nimitz
aliens deleted
typeof aliens: undefined
you sure they are gone? undefined

¡ADVERTENCIA! Cuando configura su variable como indefinida, está configurando su variable a otra variable. Si alguna persona astuta corre undefined = 'rm -rf /';, cada vez que establezca su variable como indefinida, recibirá ese valor.

Puede que se pregunte cómo puedo generar los extraterrestres de valor indefinido al principio y que aún se ejecute. Se debe a la elevación de JavaScript: http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html

Eric Leschinski
fuente
2

Prueba esto:

// found on UglifyJS
variable = void 0;
Cqq Cqq
fuente
0

El for if (something)y if (!something)se usa comúnmente para verificar si algo está definido o no. Por ejemplo:

if (document.getElementById)

El identificador se convierte en un valor booleano, por lo que undefinedse interpreta como false. Por supuesto, hay otros valores (como 0 y '') que también se interpretan comofalse , pero o bien el identificador no debe tener dicho valor de manera razonable o está contento con tratar ese valor de la misma manera que indefinido.

Javascript tiene un delete operador que puede usarse para eliminar un miembro de un objeto. Dependiendo del alcance de una variable (es decir, si es global o no), puede eliminarla para que no esté definida.

No hay una undefinedpalabra clave que pueda usar como un literal indefinido. Puede omitir parámetros en una llamada de función para hacerlos indefinidos, pero eso solo puede usarse enviando menos parámetros a la función, no puede omitir un parámetro en el medio.

Guffa
fuente
0

Solo por diversión, aquí hay una forma bastante segura de asignar "sin asignar" a una variable. Para que esto tenga una colisión, se requerirá que alguien haya agregado al prototipo de Objeto con exactamente el mismo nombre que la cadena generada aleatoriamente. Estoy seguro de que el generador de cadenas aleatorias podría mejorarse, pero acabo de tomar una de esta pregunta: generar cadenas / caracteres aleatorios en JavaScript

Esto funciona creando un nuevo objeto e intentando acceder a una propiedad con un nombre generado aleatoriamente, que suponemos que no existirá y, por lo tanto, tendrá el valor de indefinido.

function GenerateRandomString() {
    var text = "";
    var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    for (var i = 0; i < 50; i++)
        text += possible.charAt(Math.floor(Math.random() * possible.length));

    return text;
}

var myVar = {}[GenerateRandomString()];
rdans
fuente