Sempre que alguém menciona testar contra undefined
, é indicado que undefined
não é uma palavra-chave para que pudesse ser definida como"hello"
, portanto, você deve usar typeof x == "undefined"
. Isso me parece ridículo. Ninguém jamais faria isso, e se fizesse, seria motivo suficiente para nunca usar qualquer código que eles escreveram ... certo?
Eu encontrei um exemplo de alguém que acidentalmente definiu undefined
como null
, e isso foi dado como um motivo para evitar supor que undefined
não seja sobrescrito. Mas se eles tivessem feito isso, o bug não teria sido detectado, e não consigo ver como é melhor.
Em C ++, todos sabem que é legal dizer isso #define true false
, mas ninguém nunca aconselha que você evite true
e use 0 == 0
. Você simplesmente assume que ninguém jamais seria um idiota grande o suficiente para fazer isso e, se o fizer, nunca confie em seu código novamente.
Isso alguma vez realmente mordeu alguém onde outra pessoa foi atribuída undefined
(propositalmente) e quebrou seu código, ou é mais uma ameaça hipotética? Estou disposto a arriscar para tornar meu código um pouco mais legível. É realmente uma má ideia?
Para reiterar, estou não pedir como se proteger contra redeterminação indefinido. Já vi esses truques escritos 100 vezes. Estou perguntando o quão perigoso é não usar esses truques.
fonte
undefined
, você deve se preocupar mais com a redefinição de alguémXMLHttpRequest
, oualert
. Todas as funções que usamoswindow
poderiam ter sido redefinidas. E se você está apenas preocupado com um colega de trabalho fazendo isso por acidente, por que confiar que ele não faráwindow.addEventListener = "coolbeans"
? A resposta é não se preocupar com nada disso. Se alguém está injetando JS maliciosamente em sua página, você está bloqueado de qualquer maneira. Trabalhe para evitar que isso aconteça em primeiro lugar.Respostas:
Não, eu nunca fiz. Isso ocorre principalmente porque eu desenvolvo em navegadores modernos, que são em sua maioria compatíveis com ECMAScript 5. O padrão ES5 determina que
undefined
agora é somente leitura. Se você usar o modo estrito (deveria), um erro será gerado se você tentar modificá-lo acidentalmente.undefined = 5; alert(undefined); // still undefined
'use strict'; undefined = 5; // throws TypeError
O que você não deve fazer é criar seu próprio escopo, mutável
undefined
:(function (undefined) { // don't do this, because now `undefined` can be changed undefined = 5; })();
Constante está bem. Ainda desnecessário, mas ótimo.
(function () { const undefined = void 0; })();
fonte
Nenhum código adequado fará tal coisa. Mas você nunca pode saber o que algum desenvolvedor aspirante a esperto ou um plugin / biblioteca / script que você está usando fez. Por outro lado, é extremamente improvável e os navegadores modernos não permitirão a sobregravação de forma
undefined
alguma, portanto, se você estiver usando esse navegador para desenvolvimento, notará rapidamente se algum código tentar sobrescrevê-lo.E mesmo que você não tenha perguntado por isso, muitas pessoas provavelmente encontrarão essa pergunta ao procurarem o problema mais comum "como se proteger contra redefinições
undefined
", então responderei de qualquer maneira:Há uma maneira muito boa de obter um indefinido,
undefined
independentemente da idade do navegador:(function(undefined) { // your code where undefined is undefined })();
Isso funciona porque um argumento que não é especificado é sempre
undefined
. Você também pode fazer isso com uma função que aceita alguns argumentos reais, por exemplo, como este quando você está usando jQuery. Geralmente é uma boa ideia garantir um ambiente são desta forma:(function($, window, undefined) { // your code where undefined is undefined })(jQuery, this);
Então você pode ter certeza de que dentro dessa função anônima, as seguintes coisas são verdadeiras:
$ === jQuery
window === [the global object]
undefined === [undefined]
.No entanto, observe que às vezes
typeof x === 'undefined'
é realmente necessário: Se a variávelx
nunca foi definida com um valor (ao contrário de ter sido definida comoundefined
), a leiturax
de uma maneira diferente, queif(x === undefined)
gerará um erro. Isso não se aplica às propriedades do objeto, portanto, se você sabe quey
é sempre um objeto,if(y.x === undefined)
é perfeitamente seguro.fonte
x
não ter um valor definido não é totalmente verdadeira (consulte jsfiddle.net/MgADz ); é, sim, se realmente não estiver definido (consulte jsfiddle.net/MgADz/1 ).undefined = someVariable
que é um bug e você quiser que as coisas quebrem. Pelo menos eu quero.undefined
e atribua-o aoundefined
escopo. Não deixeundefined
aberto para sobrescrever se você passar "muitos" argumentos. Isso convida a erros e é um padrão inerentemente não defensivo, especialmente quando, como Lucero aponta , existem alternativas muito fáceis para obterundefined
valores sólidos no escopo.Existe uma solução simples para isso: compare com o
void 0
que é sempre indefinido.Observe que você deve evitar
==
, pois pode coagir os valores. Use===
(e!==
) em vez disso.Dito isso, a variável indefinida pode ser definida por erro se alguém escrever em
=
vez de==
ao comparar algo comundefined
.fonte
foo === void 0
leitura pode não ser tão suave quantofoo === undefined
e que imutávelundefined
é totalmente compatível com os navegadores modernos (IE 9+), como você pode ver nesta tabela de compatibilidade.Só você sabe que código usa e, portanto, o quão perigoso é. Esta pergunta não pode ser respondida da maneira que você esclareceu que gostaria que fosse respondida.
1) Crie uma política de equipe, não permita a redefinição de undefined, reservando-a para seu uso mais popular. Escaneie seu código existente para atribuição esquerda indefinida.
2) Se você não controlar todos os cenários, se seu código for usado fora das situações que você ou suas políticas controlam, obviamente sua resposta será diferente. Digitalize o código que usa seus scripts. Caramba, procure na web por estatísticas de atribuição esquerda indefinida, se desejar, mas eu duvido que isso tenha sido feito para você, porque é mais fácil apenas seguir a resposta # 1 ou # 3 aqui.
3) E se essa resposta não for boa o suficiente, provavelmente é porque, novamente, você precisa de uma resposta diferente. Talvez você esteja escrevendo uma biblioteca popular que será usada dentro de firewalls corporativos e não tenha acesso ao código de chamada. Em seguida, use uma das outras boas respostas aqui. Observe que a popular biblioteca jQuery pratica o encapsulamento de som e começa:
(function( window, undefined ) {
Só você pode responder à sua pergunta da maneira específica que procura. O que mais há pra dizer?
edit: ps se você realmente quer minha opinião, eu direi que não é perigoso. Qualquer coisa que possa causar defeitos (como atribuir a indefinidos, o que é obviamente um comportamento de risco bem documentado) é em si um defeito. É o defeito que está o risco. Mas isso é apenas em meus cenários, onde posso manter essa perspectiva. Como recomendo que você faça, respondi à pergunta para meus casos de uso.
fonte
É seguro testar contra indefinidos. Como você já mencionou. Se você obtiver algum código que o substitua (o que é altamente improvável), simplesmente não o use mais.
Talvez se você estiver criando uma biblioteca para uso público, você pode usar algumas das técnicas para evitar que o usuário a altere. Mas, mesmo neste caso, o problema é deles, não sua biblioteca.
fonte
Você pode usar
undefined
em seu código ao codificar para navegadores que suportam ECMAScript 5.1, pois é imutável de acordo com a especificação do idioma .Consulte também esta tabela de compatibilidade ou este caniuse ECMAScript 5 para ver se todos os navegadores modernos (IE 9+) foram implementados imutáveis
undefined
.fonte
Não é nada perigoso. Ele só pode ser sobrescrito quando executado em um motor ES3 e não é provável que seja usado mais.
fonte
Em primeiro lugar, se o seu código quebra, provavelmente não é porque algum outro desenvolvedor por aí "está tentando ser um idiota", como você disse.
É verdade que
undefined
não é uma palavra-chave. Mas é um primitivo de nível global. Ele foi planejado para ser usado assim (consulte "undefined" em developer.mozilla.org ):var x; if (x === undefined) { // these statements execute } else { // these statements do not execute }
A alternativa comum para isso (também do MDN ) e na minha opinião a melhor maneira é:
// x has not been declared before if (typeof x === 'undefined') { // evaluates to true without errors // these statements execute } if(x === undefined){ // throws a ReferenceError }
O que tem algumas vantagens, a óbvia (a partir dos comentários) é que não dispara uma exceção quando x não é declarado. Também é importante notar que MDN também aponta que é importante usar
===
over==
no primeiro caso porque:var x=null; if (x === undefined) { // this is probably what you meant to do // these lines will not execute in this case } else if (x == undefined) { // these statements will execute even though x *is* defined (as null) } else { // these statements do not execute }
Esse é outro motivo frequentemente esquecido pelo qual provavelmente é melhor usar apenas a segunda alternativa em todos os casos.
Conclusão: não é errado codificar da primeira forma e certamente não é perigoso. O argumento que você viu e que usa como exemplo contra ele (que pode ser sobrescrito) não é o argumento mais forte para codificar a alternativa
typeof
. Mas o usotypeof
é mais forte por um motivo específico: ele não lança uma exceção quando seu var não é declarado. Também pode-se argumentar que usar em==
vez de===
é um erro comum, caso em que não está fazendo o que você esperava. Então, por que não usartypeof
?fonte