Por que há um valor `null` em JavaScript?
Em JavaScript, existem dois valores que basicamente dizem 'Eu não existo' - undefined e null.
Uma propriedade à qual um programador não atribuiu nada será undefined, mas para que uma propriedade se torne null, null deve ser explicitamente atribuído a ela.
Eu já pensei que havia necessidade de null porque undefined é um valor primitivo e null é um objeto. Não é, mesmo que typeof null retorne 'object': Na verdade, ambos são valores primitivos - o que significa que nem undefined nem null podem ser retornados de uma função construtora, já que ambos serão convertidos em um objeto vazio (é necessário lançar um erro para declarar falha em construtores).
Eles também ambos avaliam para false em contextos booleanos. A única diferença real que posso pensar é que um avalia para NaN, o outro para 0 em contextos numéricos.
Então por que existe tanto undefined quanto null se isso apenas confunde os programadores que estão verificando incorretamente por null ao tentar descobrir se uma propriedade foi definida ou não?
O que eu gostaria de saber é se alguém tem um exemplo razoável em que seja necessário usar null que não pudesse ser expresso usando undefined em seu lugar.
Então, o consenso geral parece ser que undefined significa 'não existe tal propriedade', enquanto null significa 'a propriedade existe, mas não possui valor'.
Eu poderia conviver com isso se as implementações de JavaScript realmente aplicassem esse comportamento - mas undefined é um valor primitivo perfeitamente válido, então ele pode facilmente ser atribuído a propriedades existentes para quebrar esse contrato. Portanto, se você quiser ter certeza se uma propriedade existe, você terá que usar o operador in ou hasOwnProperty() de qualquer forma. Então, mais uma vez: qual é o uso prático de ter valores separados para undefined e null?
Na verdade, eu uso undefined quando quero limpar os valores de propriedades que não estão mais em uso, mas que eu não quero delete. Devo usar null em vez disso?
Resposta #1
A pergunta não é realmente "por que existe um valor null no JS" - existe algum tipo de valor null na maioria das linguagens e geralmente é considerado muito útil.
A questão é: "por que existe um valor undefined em JS". Principais lugares onde ele é usado:
- quando você declara
var x;mas não atribui um valor a ela,xcontém undefined; - quando sua função recebe menos argumentos do que declara;
- quando você acessa uma propriedade de objeto inexistente.
null certamente teria funcionado tão bem quanto para (1) e (2)*. (3) realmente deveria lançar uma exceção imediatamente, e o fato de não fazê-lo, em vez de retornar esse estranho undefined que falhará mais tarde, é uma grande fonte de dificuldade na depuração.
*: você também poderia argumentar que (2) deveria lançar uma exceção, mas então você teria que fornecer um mecanismo melhor e mais explícito para argumentos padrão/variáveis.
No entanto, o JavaScript originalmente não tinha exceções, nem qualquer forma de perguntar a um objeto se ele tinha um membro com determinado nome - a única forma era (e às vezes ainda é) acessar o membro e ver o que você obtém. Considerando que null já tinha um propósito e você poderia muito bem querer definir um membro como ele, era necessário um valor fora de banda diferente. Então, temos undefined, é problemático como você aponta, e é outro grande 'recurso' do JavaScript do qual nunca seremos capazes de nos livrar.
Na verdade, eu uso undefined quando quero remover os valores de propriedades que não estão mais em uso, mas que eu não quero deletar. Devo usar null em vez disso?
Sim. Mantenha undefined como um valor especial para sinalizar quando outras linguagens possam lançar uma exceção em vez disso.
null é geralmente melhor, exceto em algumas interfaces DOM do IE, onde definir algo como null pode gerar um erro. Frequentemente, nesse caso, definir como a string vazia tende a funcionar.
Resposta #2
Melhor descrito aqui, mas em resumo:
undefined é a falta de um tipo e valor, e null é a falta de um valor.
Além disso, se você está fazendo comparações simples '==', você está certo, elas dão o mesmo resultado. Mas tente '===', que compara tanto o tipo quanto o valor, e você notará a diferença.
Resposta #3
Eu não acho que haja qualquer razão para ter tanto null quanto undefined, porque a única razão que muitas pessoas sugeriram ("undefined significa que não existe tal variável/propriedade") não é válida, pelo menos em JavaScript. undefined não pode te dizer se a variável/propriedade existe ou não.
console.log(foo); // "ReferenceError: foo is not defined"
// foo does not exist
var foo;
console.log(foo); // "undefined", a different response
console.log(foo === undefined); // "true", but it does exist
var obj = {};
console.log(obj.hasOwnProperty("foo")); // "false", no such property
obj.foo = undefined;
console.log(obj.hasOwnProperty("foo")); // "true", it exists and has the value "undefined"
console.log(obj.foo === undefined); // "true", but it does exist
obj.bar = "delete me";
obj.bar = undefined;
console.log(obj.hasOwnProperty("bar")); // "true", not actually deleted
delete obj.bar;
console.log(obj.hasOwnProperty("bar")); // "false", deleted
Como você pode ver, verificar foo === undefined não lhe diz se foo existe, e definir obj.bar=undefined não apaga realmente bar.
Pode ser a intenção original do autor do JavaScript que undefined deva representar "inexistência". No entanto, a implementação não saiu dessa forma.
