No son equivalentes. La principal diferencia es esa configuración
a.x = undefined
significa que a.hasOwnProperty("x")aún devolverá verdadero, y por lo tanto, todavía se mostrará en un for inbucle, y enObject.keys()
delete a.x
significa que a.hasOwnProperty("x")devolverá falso
La forma en que son iguales es que no se puede saber si existe una propiedad mediante pruebas
if (a.x === undefined)
Lo que no debe hacer si está tratando de determinar si existe una propiedad, siempre debe usar
// If you want inherited properties
if ('x' in a)
// If you don't want inherited properties
if (a.hasOwnProperty('x'))
Seguir la cadena de prototipos (mencionada por zzzzBov ) Llamar deletele permitirá subir la cadena de prototipos, mientras que establecer el valor en indefinido no buscará la propiedad en los prototipos encadenados 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
Eliminar propiedades heredadas Si la propiedad que está intentando eliminar es heredada, deleteno la afectará. Es decir, deletesolo elimina propiedades del objeto en sí, no propiedades heredadas.
var obj = {x: "fromPrototype"};
var extended = Object.create(obj);
delete extended.x;
console.log(extended.x); // Still fromPrototype
Por lo tanto, si necesita asegurarse de que el valor de un objeto no esté definido, deleteno funcionará cuando se herede la propiedad, tendrá que establecerlo (anularlo) undefineden ese caso. A menos que se use el lugar que lo está comprobando hasOwnProperty, pero probablemente no sería seguro suponer que en todas partes que lo verifique se usaráhasOwnProperty