typeof! == “indefinido” vs.! = null

Muitas vezes vejo código JavaScript que verifica parâmetros indefinidos, etc. dessa maneira:

if (typeof input !== "undefined") { // do stuff } 

Isso parece meio que um desperdício, já que envolve tanto uma pesquisa de tipo quanto uma comparação de string, sem mencionar sua verbosidade. É necessário, porque ‘indefinido’ poderia ser renomeado, no entanto. A minha pergunta é: como é que esse código é melhor do que esta abordagem:

 if (null != input) { // do stuff } 

Tanto quanto eu sei, você não pode redefinir nulo, então não vai quebrar inesperadamente. E, por causa da coerção de tipo do operador! =, Isso verifica tanto o indefinido quanto o nulo … que geralmente é exatamente o que você deseja (por exemplo, para parâmetros de function opcionais). No entanto, essa forma não parece generalizada e faz com que o JSLint grite com você por usar o operador evil! =. Por que isso é considerado um estilo ruim?

typeof permite que o identificador nunca tenha sido declarado antes. Então, é mais seguro a esse respeito:

 if(typeof neverDeclared == "undefined") //no errors if(neverDeclared == null) //throws ReferenceError: neverDeclared is not defined 

Se a variável for declarada (com a palavra-chave var , como um argumento de function ou como uma variável global), acho que a melhor maneira de fazer isso é:

 if (my_variable === undefined) 

jQuery faz isso, então é bom o suficiente para mim 🙂

Caso contrário, você terá que usar typeof para evitar um ReferenceError .

Se você espera que o indefinido seja redefinido, você poderia quebrar seu código assim:

 (function(undefined){ // undefined is now what it's supposed to be })(); 

bom caminho:

 if(typeof neverDeclared == "undefined") //no errors 

Mas a melhor maneira é verificar via:

 if(typeof neverDeclared === typeof undefined) //also no errors and no strings 

Você não deve se preocupar com a indefinição sendo renomeada. Se alguém renomear indefinido, você terá muito mais problemas do que apenas alguns se as verificações falharem. Se você realmente quer proteger seu código, coloque-o em um IFFE (expressão de function invocada imediatamente) assim:

 (function($, Backbone, _, undefined) { //undefined is undefined here. })(jQuery, Backbone, _); 

Se você está trabalhando com variables ​​globais (o que já está errado) em um ambiente de navegador, eu verificaria indefinido assim:

 if(window.neverDefined === undefined) { //Code works } 

Como as variables ​​globais fazem parte do object window, você pode simplesmente verificar undefined em vez de converter para uma string e comparar strings.

Além disso, por que suas variables ​​não estão definidas? Eu vi um monte de código onde eles verificam a existência de uma variável e executam alguma ação com base nisso. Nem uma vez vi onde essa abordagem estava correta.

Se você está realmente preocupado com a indefinição sendo redefinida, você pode se proteger contra isso com algum método auxiliar como este:

 function is_undefined(value) { var undefined_check; // instantiate a new variable which gets initialized to the real undefined value return value === undefined_check; } 

Isso funciona porque quando alguém escreve undefined = "foo" ele apenas deixa o nome undefined referência a um novo valor, mas ele não altera o valor real de undefined .

Você também pode usar o operador void para obter um valor indefinido:

 if (input !== void 0) { // do stuff } 

(E sim, como observado em outra resposta, isso causará um erro se a variável não foi declarada, mas este caso pode ser descartado pela inspeção de código ou pela refatoração de código, por exemplo, usando window.input !== void 0 para testar variables ​​globais ou adicionar var input .)

Eu realmente encontrei if (typeof input !== 'undefined') neste cenário em que ele está sendo usado para fornecer parâmetros de function padrão:

 function greet(name, greeting) { name = (typeof name !== 'undefined') ? name : 'Student'; greeting = (typeof greeting !== 'undefined') ? greeting : 'Welcome'; return `${greeting} ${name}!`; } greet(); // Welcome Student! greet('James'); // Welcome James! greet('Richard', 'Howdy'); // Howdy Richard! 

O ES6 fornece novas maneiras de introduzir parâmetros de function padrão desta maneira:

 function greet(name = 'Student', greeting = 'Welcome') { return `${greeting} ${name}!`; } greet(); // Welcome Student! greet('James'); // Welcome James! greet('Richard', 'Howdy'); // Howdy Richard! 

Isso é menos detalhado e mais limpo que a primeira opção.

 if (input == undefined) { ... } 

funciona muito bem. É claro que não é uma comparação null , mas eu costumo achar que, se eu preciso distinguir entre undefined e null , eu realmente preciso distinguir entre undefined e qualquer valor falso, então

 else if (input) { ... } 

faz isso.

Se um programa redefine undefined , é realmente de qualquer maneira.

A única razão pela qual eu posso pensar era na compatibilidade com o IE4, ele não entendia a palavra-chave undefined (que na verdade não é uma palavra-chave, infelizmente), mas é claro que os valores poderiam ser undefined , então você precisa ter isto:

 var undefined; 

e a comparação acima funcionaria bem.

Em seu segundo exemplo, você provavelmente precisará de parênteses duplos para deixar o fiapo feliz?