jueves, 29 de agosto de 2013

JavaScript: El operador 'delete'

El operador delete es un incomprendido. No sirve para borrar variables y muchas veces tratamos de utilizarlo incorrectamente. Hay dos claves muy importantes:

  • delete sirve para borrar propiedades de un objeto
  • No puedes borrar con delete ninguna variable declarada con var

La forma de usarlo es:

delete object.property

Por ejemplo:


var myObj = {
    uno: 1,
    dos: 2
};
delete myObj.uno;
console.log( myObj.uno ); // undefined

La propiedad borrada deja de existir, ya no aparecerá en las iteraciones.

delete sólo funciona sobre propiedades de objetos. No hace nada aplicado sobre variables o funciones:

var test = "no puedes borrarme";
delete test;
console.log( test ); // "no puedes borrarme"

Nota: eval(), utilizado por firebug y otras consolas de navegador, modifica la forma en la que se crean las variables, afectando al funcionamiento de delete. Estos ejemplos no pueden probarse correctamente en la consola. Es necesario crear un script para evaluarlos en una página real cargada en el navegador.

Las variables globales declaradas sin var sí pueden borrarse. Sería equivalente crearlas como una propiedad del objeto global window:


test = "Sí puedes borrarme, soy window.test";
console.log(test);           //"Sí puedes borrarme, soy window.test"
console.log(window.test);    //"Sí puedes borrarme, soy window.test"
delete test;
console.log(test);           // ReferenceError: test is not defined

Como vimos antes, esta misma variable global declarada con var NO puede borrarse.

Delete devuelve un boolean

El operador devuelve true si la propiedad referenciada ya no existe y false si aún existe. Es muy importante tener en cuenta que el valor devuelto no indica exactamente si la operación ha tenido éxito o no, sino si la propiedad referenciada existe ahora o no. Si intentamos borrar una propiedad que no existía obtenemos true.


var test1 = "no puedes borrarme";
test2 = "sí puedes borrarme";
var myObj = {
    uno: 1,
    dos: 2
};    

delete test1;        // false    
delete test2;        // true
delete test3;        // true!!. test3 no existía    
delete myObj.uno;    // true
delete myObj.cuatro; // true!!. 'myObj.cuatro' no existía

Los argumentos de una función no se borran

Los argumentos de una función son equivalentes a variables declaradas dentro de la función mediante var, por lo tanto, no podemos borrarlos:

function suma (arg1, arg2) {
    delete arg1; //false. No hace nada
    //...
}  

Hay propiedades 'especiales' que no pueden borrarse

La mayoría de las propiedades de los objetos predefinidos de JavaScript, como Array, Object, Math, etc, están marcadas con un flag especial que impide borrarlas (el atributo DontDelete). Esto impide, por ejemplo, borrar .length en un array:

delete [].length; // false
delete Math.PI;   // false

Propiedades heredadas del prototipo

No podemos borrar directamente una propiedad heredada. Tenemos que borrarla desde su objeto original (el prototipo):


function MyConstructor(){}
MyConstructor.prototype.test = "Hello";
var myObject = new MyConstructor();
delete myObject.test;                 // no hace nada
console.log(myObject.test);           // "Hello"
delete MyConstructor.prototype.test;  // borra la propiedad en el prototipo
console.log(myObject.test);           // "undefined"

Comportamiento en ES5

ECMAScript 5th edition introduce algunas novedades. Básicamente nuevos tipos de error para notificar el uso inapropiado:

  • Intentar borrar una variable, un argumento de función o una función provoca un SyntaxError
  • Borrar una variable inexistente provoca un SyntaxError

(function (arg1) {

    "use strict"; // activar modo estricto (ES5) 

    var test;
    function sum(){}

    delete arg1;  // SyntaxError (when deleting argument)
    delete test;  // SyntaxError (when deleting variable)
    delete sum;   // SyntaxError (when deleting variable created with function declaration)
    delete i_dont_exist; // SyntaxError

  })();

Fuentes:
Perfection Kills: Understanding delete
You Can’t Delete With Delete
StackOverflow: deleting objects in javascript
MDN: delete

No hay comentarios:

Publicar un comentario