Posso definir variáveis ​​como indefinidas ou passar indefinidas como argumento?


304

Estou um pouco confuso sobre JavaScript undefinede nullvalores.

O que if (!testvar)realmente faz? Ele testa undefinede nullou apenas undefined?

Depois que uma variável é definida, posso limpá-la novamente undefined(excluindo a variável)?

Posso passar undefinedcomo parâmetro? Por exemplo:

function test(var1, var2, var3) {

}

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

Respostas:


514

Estou um pouco confuso sobre Javascript indefinido e nulo.

Não fique confuso null. Geralmente, faz sentido e se comporta de maneira semelhante aos conceitos de outras linguagens de script dos objetos 'nulo', 'nulo' ou 'Nenhum' fora da banda.

undefined, por outro lado, é uma peculiaridade estranha do JavaScript. É um objeto singleton que representa valores fora da banda, essencialmente um segundo semelhante, mas diferente null. Ele aparece:

  1. Quando você chama uma função com menos argumentos que a lista de argumentos nas functionlistas de instruções, os argumentos não passados ​​são definidos como undefined. Você pode testar isso com, por exemplo:

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

    Com este método, você não pode dizer a diferença entre dosomething(1)e dosomething(1, undefined); arg2terá o mesmo valor em ambos. Se você precisar dizer a diferença, pode observar arguments.length, mas executar argumentos opcionais como esse geralmente não é muito legível.

  2. Quando uma função não tem return value;, ela retorna undefined. Geralmente, não há necessidade de usar esse resultado de retorno.

  3. Quando você declara uma variável tendo uma var ainstrução em um bloco, mas ainda não atribuiu um valor a ela, é isso undefined. Novamente, você realmente não precisa confiar nisso.

  4. O typeofoperador assustador retorna 'undefined'quando seu operando é uma variável simples que não existe, em vez de gerar um erro, como normalmente aconteceria se você tentasse fazer referência a ele. (Você também pode fornecer uma variável simples entre parênteses, mas não uma expressão completa que envolva uma variável inexistente.) Também não é muito útil para isso.

  5. Este é o controverso. Quando você acessa uma propriedade de um objeto que não existe, você não recebe imediatamente um erro como em qualquer outro idioma. Em vez disso, você recebe um undefinedobjeto. (E então, quando você tentar usar esse undefinedobjeto posteriormente no script, ele sairá errado de uma maneira estranha, muito mais difícil de rastrear do que se o JavaScript tivesse lançado um erro imediatamente.

    Isso geralmente é usado para verificar a existência de propriedades:

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

    No entanto, porque você pode atribuir undefinedcomo qualquer outro valor:

    o.prop= undefined;

    que não detecta se a propriedade existe de forma confiável. Melhor usar o inoperador, que não estava na versão original do JavaScript do Netscape, mas está disponível em qualquer lugar agora:

    if ('prop' in o)
        ...

Em resumo, undefinedé uma bagunça específica do JavaScript, que confunde todo mundo. Além dos argumentos de função opcionais, onde JS não possui outro mecanismo mais elegante, undefineddeve ser evitado. Nunca deveria ter sido parte da linguagem; nullteria funcionado bem para (2) e (3) e (4) é uma falha de funcionalidade que só existe porque no início o JavaScript não tinha exceções.

o que if (!testvar)realmente faz? Ele testa indefinido e nulo ou apenas indefinido?

Um 'truthiness' tais verificações de teste contra false, undefined, null, 0, NaNe cadeias vazias. Mas, neste caso, sim, é realmente com o undefinedque está preocupado. OMI, deve ser mais explícito sobre isso e dizer if (testvar!==undefined).

Depois que uma variável é definida, posso restaurá-la para indefinida (portanto, excluindo a variável).

Você pode certamente atribuir undefineda ele, mas isso não excluirá a variável. Somente o delete object.propertyoperador realmente remove as coisas.

deleteé realmente destinado a propriedades, e não a variáveis ​​como tais. Os navegadores permitem que você se dê bem delete variable, mas não é uma boa ideia e não funcionará no modo estrito do ECMAScript Fifth Edition. Se você deseja liberar uma referência a algo para que possa ser coletado no lixo, seria mais comum dizer isso variable= null.

posso passar indefinido como parâmetro?

Sim.


10
Que resposta fantástica. Acabei de falhar no teste de JavaScript: perfectionkills.com/javascript-quiz Mais tarde, vou reler sua resposta e tentar o teste novamente!
Skilldrick

1
fixo, ta. (I tendem a não se preocupar muito com reafectação, como há tantas coisas que um script poderia redefinir a estragar tudo que o caso geral é impossível de resolver.)
bobince

2
@bince undefinedé um objeto singleton? O que você quer dizer? É um valor primitivo, e não um objeto.
Šime Vidas

2
@Hortitude: Esse é o ponto (4). Eu geralmente não typeof foo=='undefined'; ele tende a ser usado para (4a) detecção global, caso em que eu preferiria ser explícito e dizer 'foo' in window, ou (4b) testar contra oundefined próprio valor -, caso em que eu preferiria ser legível e dizer foo===undefined. Em teoria, o teste typeofcontra 'undefined'poderia ter um caso de uso que outras construções não poderiam fornecer: farejar a existência de variáveis ​​locais. No entanto, na realidade, você quase sempre sabe quais variáveis ​​são declaradas locais.
bobince

4
Uma ressalva com o número 2, geralmente uma função sem returnretorno de instrução undefined, mas se a função for um construtor (invocado pelo newoperador), ele retornará o novo objeto (o valor de thisdentro do construtor) apesar de não ter uma returninstrução. console.log((function (){}()));retorna undefined. console.log((new function (){}()));retorna um objeto.
Código inútil

18

Você não pode (não deveria?) Definir nada como indefinido, pois a variável não seria mais indefinida - você apenas definiu como algo.

Você não pode (não deveria?) Passar undefinedpara uma função. Se você deseja passar um valor vazio, use null.

A instrução if(!testvar)verifica valores booleanos true / false, este em particular testa se é testvaravaliado false. Por definição, nulle undefinednão deve ser avaliado nem como trueou false, mas o JavaScript avalia nullcomo falsee gera um erro se você tentar avaliar uma variável indefinida.

Para testar adequadamente undefined ou null, use estes:

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

if(testvar === null) { ... }

1
O triplo-igual verifica também o tipo, para que nenhuma coerção seja realizada. Douglas Crockford desaconselha o uso dos operadores de coação de tipo ( ==e !=).
Skilldrick

3
Você pode definir algo como indefinido. var a= undefined. Você pode passar fn(undefined). Se você deseja encontrar a diferença entre uma propriedade indefinida pde um objeto oe uma propriedade pque foi definida e definida como undefined, você deve usar o 'p' in ooperador.
22910

1
Existe uma razão pela qual não se deve testar testvar === undefinede não o mais complicado typeof(testvar) === "undefined"?
DDAA

4
Há outra boa razão para usar um typeofteste para variáveis ​​indefinidas: ao contrário null, undefinedé simplesmente uma propriedade do objeto global e pode ser redefinida. É necessário apenas um estilo de codificação específico e um sinal de igual ausente e undefinedé alterado silenciosamente: #:if (undefined = someVar) {...}
Tim Down

1
@IanGrainger: O ECMAScript 5 (implementado nas versões atuais de todos os navegadores) corrige isso principalmente criando undefineduma propriedade imutável do objeto global, para que seja mais seguro do que costumava ser. No entanto, ainda é possível definir uma variável mutável chamada undefineddentro de uma função, para que o problema não tenha desaparecido completamente.
Tim Down

13

A diferença básica é isso undefinede nullrepresenta conceitos diferentes.

Se apenas nullestivesse disponível, você não seria capaz de determinar se nullfoi definido intencionalmente como o valor ou se o valor ainda não foi definido, a menos que você tenha utilizado a captura de erros pesados: por exemplo

var a;

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

No entanto, se você definir intencionalmente o valor como null, igualdade estrita com undefinedfalhas, permitindo diferenciar entre nulle undefinedvalores:

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

Confira a referência aqui, em vez de confiar nas pessoas dizendo desdenhosamente como "Em resumo, indefinido é uma bagunça específica do JavaScript, que confunde todo mundo". Só porque você está confuso, isso não significa que está uma bagunça.

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

Este comportamento também não é específico para JavaScript e completa o conceito generalizado que um resultado boolean pode ser true, false, desconhecido ( null), nenhum valor ( undefined), ou algo deu errado ( error).

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


E ainda nullteria funcionado muito bem. a == nullé trueporque a coerção do tipo Javascript.
sleepwalkerfx

11

A melhor maneira de verificar valores nulos é

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

e por indefinido

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

Você pode atribuir uma variável com indefinida.

testVar = undefined;
//typeof(testVar) will be equal to undefined.

1
A melhor maneira de verificar se há valores nulos é usar !==, não!=
MBO

6

SIM, você pode, porque indefinido é definido como indefinido.

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

seu caso:

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

você também pode criar sua própria variável indefinida:

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

5

Para responder sua primeira pergunta, o operador not ( !) forçará o que quer que seja fornecido em um valor booleano. Assim null, 0, false, NaNe ""(string vazia) serão todos parecem falsas.


E também string vazia e NaN (Não é um número)
MBO

undefinednão aparecerá como false, lançará um erro 'não está definido'.
Tatu Ulmanen

Tatu Ulmanen: não é verdade. if (undefined) {/* Do stuff*/}não dará um erro, pois undefinedexiste como uma propriedade do objeto global. O que causará um erro é algo comoif (someUndeclaredVariable) {/* Do stuff*/}
Tim Down

2

JavaScript, como definir uma variável como indefinida na linha de comando:

Defina uma variável como indefinida no jsterminal da linha de comando javascript que acompanha o Java no 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

Se você definir uma variável como indefinida em um javascript:

Coloque isso em 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 isto:

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

AVISO! Ao configurar sua variável como indefinida, você está configurando sua variável para outra variável. Se alguma pessoa sorrateira executar undefined = 'rm -rf /';, sempre que você definir sua variável como indefinida, você receberá esse valor.

Você pode estar se perguntando como eu posso gerar o valor indefinido de alienígenas no início e ainda executá-lo. É por causa da elevação do javascript: http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html


2

Tente o seguinte:

// found on UglifyJS
variable = void 0;

0

O for if (something)e if (!something)é comumente usado para verificar se algo está definido ou não. Por exemplo:

if (document.getElementById)

O identificador é convertido em um valor booleano e, portanto, undefinedé interpretado como false. É claro que existem outros valores (como 0 e '') que também são interpretados comofalse , mas o identificador não deve ter um valor razoável ou você está satisfeito em tratá-lo da mesma forma que o indefinido.

Javascript tem um deleteoperador que pode ser usado para excluir um membro de um objeto. Dependendo do escopo de uma variável (por exemplo, se é global ou não), você pode excluí-la para torná-la indefinida.

Não há nenhuma undefinedpalavra-chave que você possa usar como um literal indefinido. Você pode omitir parâmetros em uma chamada de função para torná-los indefinidos, mas isso só pode ser usado enviando menos parâmetros para a função; você não pode omitir um parâmetro no meio.


0

Apenas por diversão, aqui está uma maneira bastante segura de atribuir "não atribuído" a uma variável. Para que isso ocorra uma colisão, é necessário que alguém seja adicionado ao protótipo de Objeto com exatamente o mesmo nome que a sequência gerada aleatoriamente. Tenho certeza de que o gerador de cadeias aleatórias poderia ser melhorado, mas acabei de tirar uma desta pergunta: Gere cadeias / caracteres aleatórios em JavaScript

Isso funciona criando um novo objeto e tentando acessar uma propriedade com um nome gerado aleatoriamente, que estamos assumindo que não existirá e, portanto, terá o 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()];
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.