Eles não são equivalentes. A principal diferença é que a configuração
a.x = undefined
significa que a.hasOwnProperty("x")ainda retornará verdadeiro e, portanto, ainda aparecerá em um for inloop e emObject.keys()
delete a.x
significa que a.hasOwnProperty("x")retornará falso
A maneira como eles são iguais é que você não pode dizer se existe uma propriedade testando
if (a.x === undefined)
O que você não deve fazer se estiver tentando determinar se existe uma propriedade, sempre use
// If you want inherited properties
if ('x' in a)
// If you don't want inherited properties
if (a.hasOwnProperty('x'))
Após a cadeia de protótipos (mencionada por zzzzBov ) A chamada deletepermitirá que ela suba a cadeia de protótipos, enquanto definir o valor como indefinido não procurará a propriedade nos protótipos encadeados http://jsfiddle.net/NEEw4/1/
var obj = {x: "fromPrototype"};
var extended = Object.create(obj);
extended.x = "overriding";
console.log(extended.x); // overriding
extended.x = undefined;
console.log(extended.x); // undefined
delete extended.x;
console.log(extended.x); // fromPrototype
Exclusão de propriedades herdadas Se a propriedade que você está tentando excluir for herdada, deletenão a afetará. Ou seja, deletesomente exclui propriedades do próprio objeto, não propriedades herdadas.
var obj = {x: "fromPrototype"};
var extended = Object.create(obj);
delete extended.x;
console.log(extended.x); // Still fromPrototype
Portanto, se você precisar garantir que o valor de um objeto seja indefinido, deletenão funcionará quando a propriedade for herdada, será necessário configurá-la (substituí-la) undefinednesse caso. A menos que o local que está verificando ele use hasOwnProperty, mas provavelmente não seria seguro supor que em todos os lugares que o verifiquemhasOwnProperty