remove - vaciar objeto javascript




¿Cómo elimino una propiedad de un objeto JavaScript? (20)

Digamos que creo un objeto de la siguiente manera:

var myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI",
    "regex": "^http://.*"
};

¿Cuál es la mejor manera de eliminar la propiedad de regex para terminar con el nuevo myObject siguiente manera?

var myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI"
};

2 (ES6)

Para quien lo necesite ...

Para completar la respuesta de @Koen en este hilo, en caso de que quiera eliminar una variable dinámica utilizando la sintaxis de propagación, puede hacerlo así:

const key = 'a';

const { [key]: foo, ...rest } = { a: 1, b: 2, c: 3 };

console.log(rest); // { b: 2, c: 3 }

* fooserá una nueva variable con el valor de a(que es 1).


ACTUALIZACIÓN :
hay algunas formas comunes de eliminar una propiedad de un objeto.
Cada uno tiene sus pros y sus contras ( consulte esta comparación de rendimiento ):

developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
legible y breve, sin embargo, podría no ser la mejor opción si está operando en una gran cantidad de objetos, ya que su rendimiento no está optimizado.

delete obj[key];


Reassignment
Más de 2 veces más rápido quedelete, sin embargo, la propiedadno seelimina y se puede iterar.

obj[key] = null;
obj[key] = false;
obj[key] = undefined;


Operador de propagación
EsteES6operador nos permite devolver un objeto nuevo, excluyendo cualquier propiedad, sin mutar el objeto existente. El inconveniente es que tiene el peor rendimiento de lo anterior y no se sugiere que se use cuando necesite eliminar muchas propiedades a la vez.

{ [key]: val, ...rest } = obj;

Eliminación de propiedad en JavaScript

Hay muchas opciones diferentes presentadas en esta página, no porque la mayoría de las opciones sean incorrectas o porque las respuestas son duplicados, sino porque la técnica adecuada depende de la situación en la que se encuentre y de los objetivos de las tareas en las que usted y / o usted El equipo está tratando de cumplir. Para responder a su pregunta de manera inequívoca, uno necesita saber:

  1. La versión de ECMAScript que estás apuntando
  2. El rango de tipos de objetos en los que desea eliminar las propiedades y el tipo de nombres de propiedades que necesita para poder omitir (¿Sólo cadenas? ¿Símbolos? ¿Referencias débiles asignadas desde objetos arbitrarios? Todos estos han sido tipos de punteros de propiedad en JavaScript desde hace años )
  3. La ética de programación / patrones que usted y su equipo usan. ¿Prefiere los enfoques funcionales y la mutación es verboten en su equipo, o emplea técnicas orientadas a objetos mutativos del salvaje oeste?
  4. ¿Está buscando lograr esto en JavaScript puro o está dispuesto y puede usar una biblioteca de terceros?

Una vez que se han respondido esas cuatro consultas, hay esencialmente cuatro categorías de "eliminación de propiedades" en JavaScript para elegir a fin de cumplir sus objetivos. Son:

Eliminación de propiedad de objeto mutativo, inseguro

Esta categoría es para operar en literales de objetos o instancias de objetos cuando desea conservar / continuar usando la referencia original y no está utilizando principios funcionales sin estado en su código. Un ejemplo de sintaxis en esta categoría:

'use strict'
const iLikeMutatingStuffDontI = { myNameIs: 'KIDDDDD!', [Symbol.for('amICool')]: true }
delete iLikeMutatingStuffDontI[Symbol.for('amICool')] // true
Object.defineProperty({ myNameIs: 'KIDDDDD!', 'amICool', { value: true, configurable: false })
delete iLikeMutatingStuffDontI['amICool'] // throws

Esta categoría es la categoría de eliminación de propiedad más antigua, directa y con mayor respaldo. Admite Symbolíndices de matrices, además de cadenas, y funciona en todas las versiones de JavaScript, excepto en la primera versión. Sin embargo, es mutativo lo que viola algunos principios de programación y tiene implicaciones de rendimiento. También puede dar lugar a excepciones no detectadas cuando se utiliza en developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… .

Omisión de propiedad de cadena basada en el resto

Esta categoría es para operar en objetos simples o en instancias de matriz en versiones más recientes de ECMAScript cuando se desea un enfoque no mutativo y no es necesario tener en cuenta las teclas de símbolos:

const foo = { name: 'KIDDDDD!', [Symbol.for('isCool')]: true }
const { name, ...coolio } = foo // coolio doesn't have "name"
const { isCool, ...coolio2 } = foo // coolio2 has everything from `foo` because `isCool` doesn't account for Symbols :(

Supresión de propiedad de objeto mutativo, segura

Esta categoría es para operar en literales de objetos o instancias de objetos cuando desea conservar / continuar usando la referencia original y evitar que se generen excepciones en propiedades no configurables:

'use strict'
const iLikeMutatingStuffDontI = { myNameIs: 'KIDDDDD!', [Symbol.for('amICool')]: true }
Reflect.deleteProperty(iLikeMutatingStuffDontI, Symbol.for('amICool')) // true
Object.defineProperty({ myNameIs: 'KIDDDDD!', 'amICool', { value: true, configurable: false })
Reflect.deleteProperty(iLikeMutatingStuffDontI, 'amICool') // false

Además, si bien la mutación de objetos en el lugar no es sin estado, puede utilizar la naturaleza funcional de Reflect.deletePropertyla aplicación parcial y otras técnicas funcionales que no son posibles con las deletedeclaraciones.

Omisión basada en la sintaxis propiedad de la cadena

Esta categoría es para operar en objetos simples o en instancias de matriz en versiones más recientes de ECMAScript cuando se desea un enfoque no mutativo y no es necesario tener en cuenta las teclas de símbolos:

const foo = { name: 'KIDDDDD!', [Symbol.for('isCool')]: true }
const { name, ...coolio } = foo // coolio doesn't have "name"
const { isCool, ...coolio2 } = foo // coolio2 has everything from `foo` because `isCool` doesn't account for Symbols :(

Omisión de propiedad basada en la biblioteca

Esta categoría generalmente permite una mayor flexibilidad funcional, incluida la contabilización de símbolos y omitir más de una propiedad en una declaración:

const o = require("lodash.omit")
const foo = { [Symbol.for('a')]: 'abc', b: 'b', c: 'c' }
const bar = o(foo, 'a') // "'a' undefined"
const baz = o(foo, [ Symbol.for('a'), 'b' ]) // Symbol supported, more than one prop at a time, "Symbol.for('a') undefined"

¡La delete operador es inesperadamente lenta!

Mira el benchmark .

Eliminar es la única forma verdadera de eliminar las propiedades del objeto sin restos, pero funciona ~ 100 veces más lento , en comparación con su "alternativa", estableciendo el object[key] = undefined .

¡Esta alternativa no es la respuesta correcta a esta pregunta! Pero, si lo usa con cuidado, puede acelerar dramáticamente algunos algoritmos. Si está utilizando delete en bucles y tiene problemas con el rendimiento, lea la explicación detallada.

¿Cuándo se debe usar delete y cuando se establece un valor como undefined ?

Un objeto puede verse como un conjunto de pares clave-valor. Lo que yo llamo un 'valor' es una primitiva o una referencia a otro objeto, conectado a esa 'clave'.

Utilice delete , cuando esté pasando el objeto resultante al código sobre el que no tiene control (o cuando no esté seguro de su equipo o de usted mismo).

Borra la clave del hashmap .

 var obj = {
     field: 1     
 };
 delete obj.field;

Use la configuración para undefined , cuando le importa el rendimiento. Puede dar un gran impulso a su código.

La clave permanece en su lugar en el hashmap , solo el valor se reemplaza por undefined . Comprende, que para for..in bucle todavía se repetirá sobre esa clave.

 var obj = {
     field: 1     
 };
 obj.field = undefined;

Usando este método, no todas las formas de determinar la existencia de una propiedad funcionarán como se espera.

Sin embargo, este código:

object.field === undefined

Se comportará de manera equivalente para ambos métodos.

Pruebas

Para resumir, las diferencias tienen que ver con las formas de determinar la existencia de la propiedad, y sobre el bucle for..in .

 console.log('* -> "Takes prototype inheritance into consideration, that means it lookups all over prototype chain too."');

 console.log(obj.field === undefined, 'obj.field === undefined', 'You get "undefined" value when querying for "field" in object-hashmap. *');

 console.log(obj["field"] === undefined, 'obj["field"] === undefined', 'Just another way to query (equivalent). *');

 console.log(typeof obj.field === "undefined", 'typeof obj.field === "undefined"', 'Get the value attached to "field" key, and check it\'s type is "undefined". *');

 console.log("field" in obj, '"field" in obj', 'This statement returns true if "field" key exists in the hashmap. False otherwise. *');

 console.log(obj.hasOwnProperty("field"), 'obj.hasOwnProperty("field")', 'This statement returns true if \'field\' key exists in the hashmap. The ONLY way NOT to lookup for property in the prototype chain!');
 //Object.keys().indexOf() is an overkill that runs much slower :)

 var counter = 0,
     key;
 for (key in obj) {
     counter++;
 }
 console.assert(counter === 0, 'counter === 0', '"field" is not iterated using "for .. in" loop. *');

¡Cuidado con las fugas de memoria!

Si bien usar obj[prop] = undefined es más rápido que delete obj[prop] , otra consideración importante es que obj[prop] = undefined no siempre es apropiado. delete obj[prop] elimina prop de obj y lo borra de la memoria, mientras que obj[prop] = undefined simplemente establece el valor de prop en undefined que deja a prop en la memoria. Por lo tanto, en circunstancias donde se crean y eliminan muchas claves, el uso de obj[prop] = undefined puede forzar una costosa reconciliación de la memoria (lo que provoca que la página se congele) y posiblemente un error de falta de memoria. Examina el siguiente código.

"use strict";
var theNodeList=[], i, current, numberOfNodes=65536, body=document.body, nodeRecords=[];
for (i = 0; i !== numberOfNodes; i++) {
    nodeRecords[i] = [];
    current = theNodeList[i] = document.createElement("div");
    current.textContent = i;
    document.body.appendChild( current );
}
var lastTime = -1;
requestAnimationFrame(function recordUpdates(){
    var currentTime = Math.round( performance.now()*1000 )
    for (i = 0; i !== numberOfNodes; i++) {
        if (lastTime !== -1) {
            // the previously collected data is no longer in use
            /*************************************************/
            /****/ nodeRecords[i][lastTime] = undefined; /****/
            /*************************************************/
        }
        nodeRecords[i][currentTime] = theNodeList[i].outerHTML;
    }
    lastTime = currentTime;
    requestAnimationFrame( recordUpdates );
});

En el código anterior, simplemente haciendo nodeRecords[i][lastTime] = undefined; causará una pérdida de memoria masiva porque cada cuadro de animación. En cada cuadro, todos los 65536 elementos DOM ocuparán otras 65536 ranuras individuales, pero las ranuras 65536 anteriores solo se configurarán como indefinidas, lo que las deja colgadas en la memoria. Adelante, intente ejecutar el código anterior en la consola y ver por sí mismo. Después de forzar un error de memoria insuficiente, intente ejecutarlo nuevamente, excepto con la siguiente versión del código que usa el operador de delete lugar.

"use strict";
var theNodeList=[], i, current, numberOfNodes=65536, body=document.body, nodeRecords=[];
for (i = 0; i !== numberOfNodes; i++) {
    nodeRecords[i] = [];
    current = theNodeList[i] = document.createElement("div");
    current.textContent = i;
    document.body.appendChild( current );
}
var lastTime = -1;
requestAnimationFrame(function recordUpdates(){
    var currentTime = Math.round( performance.now()*1000 )
    for (i = 0; i !== numberOfNodes; i++) {
        if (lastTime !== -1) {
            // the previously collected data is no longer in use
            /********************************************/
            /****/ delete nodeRecords[i][lastTime]; /****/
            /********************************************/
        }
        nodeRecords[i][currentTime] = theNodeList[i].outerHTML;
    }
    lastTime = currentTime;
    requestAnimationFrame( recordUpdates );
});

Como se ve en el fragmento de código anterior, hay algunos casos de uso raros y apropiados para el operador de delete . Sin embargo, no te preocupes demasiado por este problema. Esto solo se convertirá en un problema con los objetos de larga duración que se agregan constantemente nuevas claves. En cualquier otro caso (que es casi todos los casos en la programación del mundo real), es más apropiado usar obj[prop] = undefined . El propósito principal de esta sección es solo llamar su atención para que, en la rara ocasión de que esto se convierta en un problema en su código, pueda entender el problema más fácilmente y, por lo tanto, no tenga que perder horas para analizar su código para localizarlo. y entender este problema.

No siempre se establece en undefined

Un aspecto de Javascript que es importante tener en cuenta es el polimorfismo. El polimorfismo es cuando se asignan los mismos tipos de variable / slot-in-an-object como se ve a continuación.

var foo = "str";
foo = 100;          // variable foo is now labeled polymorphic by the browser
var bar = ["Some", "example"];
bar[2] = "text";    // bar is a monomorphic array here because all its entries have the
                    // same type: string primitive
bar[1] = undefined; // bar is now a polymorphic array

Sin embargo, hay dos problemas principales que no se pueden arreglar con matrices polimórficas:

  1. Son lentos y la memoria ineficiente. Al acceder a un índice específico, en lugar de obtener el tipo global para la matriz, el navegador tiene que obtener el tipo por índice, por lo que cada índice almacena los metadatos adicionales de su tipo.
  2. Una vez polimórficos, siempre polimórficos. Cuando una matriz se hace polimórfica, el polimorfismo no se puede deshacer en los navegadores Webkit. Por lo tanto, incluso si restaura una matriz polimórfica a no ser polimórfica, el navegador aún la almacenará como una matriz polimórfica.

Uno puede comparar el polimorfismo con una adicción a las drogas. A primera vista, parece asombrosamente lucrativo: un código bonito y esponjoso. Luego, el codificador introduce su matriz al fármaco del polimorfismo. Al instante, la matriz polimórfica se vuelve menos eficiente, y nunca puede volverse tan eficiente como lo era antes, ya que está drogado. Para correlacionar esta circunstancia con la vida real, una persona que consume cocaína podría no ser capaz de operar una simple manija de la puerta, y mucho menos poder calcular los dígitos de PI. Del mismo modo, una matriz sobre el fármaco del polimorfismo nunca puede ser tan eficiente como una matriz monomórfica.

Pero, ¿cómo se relaciona una analogía con el viaje de drogas a la operación de delete ? La respuesta hereda la última línea de código en el fragmento anterior. Por lo tanto, deja que se vuelva a examinar, esta vez con un toque.

var bar = ["Some", "example"];
bar[2] = "text";    // bar is not a polymorphic array here because all its entries have the
                    // same type: string primitive
bar[1] = "";        // bar is still a monomorphic array
bar[1] = undefined; // bar is now a polymorphic array

Observar. bar[1] = "" no obliga al polimorfismo, mientras que la bar[1] = undefined hace. Por lo tanto, siempre debe ser posible, siempre que sea posible, usar el tipo correspondiente para sus objetos para no causar accidentalmente el polimorfismo. Una de esas personas puede usar la siguiente lista como referencia general para ponerla en marcha. Sin embargo, no utilice explícitamente las ideas a continuación. En su lugar, use lo que funcione bien para su código.

  • Cuando se usa una matriz / variable escrita en el primitivo booleano, use false o undefined como el valor vacío. Mientras que evitar el polimorfismo innecesario es bueno, reescribir todo el código para prohibirlo de manera explícita probablemente resultará en una disminución en el rendimiento. ¡Usa el juicio común!
  • Cuando se usa una matriz / variable escrita con el número primitivo, use 0 como el valor vacío. Tenga en cuenta que, internamente, hay dos tipos de números: enteros rápidos (2147483647 a -2147483648 inclusive) y dobles de punto flotante lento (todo lo que incluye a NaN e Infinity ). Cuando un entero se reduce a un doble, no se puede volver a promover a un entero.
  • Cuando use una matriz / variable escrita en el primitivo de cadena, use "" como el valor vacío.
  • Cuando use un Símbolo, espere, ¿por qué usa un Símbolo?!?! Los símbolos son malos juju para el rendimiento. Todo lo programado para usar Símbolos puede reprogramarse para que no use Símbolos, lo que resulta en un código más rápido sin Símbolos. Los símbolos son realmente meta-azúcar super ineficiente.
  • Cuando uses cualquier otra cosa, usa null .

Sin embargo, se atento! No comience a hacer esto repentinamente con todo su código preexistente ahora ya que probablemente rompería dicho código preexistente y / o introduciría errores extraños. Más bien, tal práctica eficiente debe implementarse desde el principio, y al convertir el código preexistente, se recomienda que doble, triple, cuádruple verifique todas las líneas relacionadas con eso, ya que tratar de actualizar el código antiguo a esta nueva práctica puede ser tan Riesgo ya que es gratificante.


El término que ha usado en el título de su pregunta Remove a property from a JavaScript object , puede interpretarse de diferentes maneras. La primera es eliminarla por completo de la memoria y la lista de claves de objeto o la otra es eliminarla de su objeto. Como se ha mencionado en algunas otras respuestas, la palabra clave de delete es la parte principal. Digamos que tienes tu objeto como:

myJSONObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};

Si lo haces:

console.log(Object.keys(myJSONObject));

El resultado sería:

["ircEvent", "method", "regex"]

Puede eliminar esa clave específica de sus claves de objeto como:

delete myJSONObject["regex"];

Entonces su clave de objetos usando Object.keys(myJSONObject) sería:

["ircEvent", "method"]

Pero el punto es que si le importa la memoria y desea que el objeto se elimine de la memoria, se recomienda establecerlo en nulo antes de eliminar la clave:

myJSONObject["regex"] = null;
delete myJSONObject["regex"];

El otro punto importante aquí es tener cuidado con sus otras referencias al mismo objeto. Por ejemplo, si creas una variable como:

var regex = myJSONObject["regex"];

O agregarlo como un nuevo puntero a otro objeto como:

var myOtherObject = {};
myOtherObject["regex"] = myJSONObject["regex"];

Entonces, incluso si lo elimina de su objeto myJSONObject , ese objeto específico no se eliminará de la memoria, ya que la variable regex y myOtherObject["regex"] aún tienen sus valores. Entonces, ¿cómo podríamos eliminar el objeto de la memoria con seguridad?

La respuesta sería eliminar todas las referencias que tiene en su código, apuntadas a ese mismo objeto y no usar las declaraciones var para crear nuevas referencias a ese objeto . Este último punto con respecto a las declaraciones var , es uno de los problemas más cruciales con los que nos enfrentamos habitualmente, porque el uso de las declaraciones var evitaría que el objeto creado se elimine.

Lo que significa que en este caso no podrá eliminar ese objeto porque ha creado la variable regex través de una declaración var , y si lo hace:

delete regex; //False

El resultado sería false , lo que significa que su declaración de eliminación no se ha ejecutado como esperaba. Pero si no había creado esa variable anteriormente, y solo tenía myOtherObject["regex"] como su última referencia existente, podría haberlo hecho simplemente eliminándolo como:

myOtherObject["regex"] = null;
delete myOtherObject["regex"];

En otras palabras, un objeto JavaScript se anula tan pronto como no queda ninguna referencia en su código que apunta a ese objeto.

Actualización: Gracias a @AgentME:

Establecer una propiedad en nulo antes de eliminarlo no logra nada (a menos que Object.seal haya sellado el objeto y se produzca un error en la eliminación. Ese no suele ser el caso a menos que lo intente específicamente).

Para obtener más información sobre Object.seal : Object.seal()


Otra alternativa es usar la biblioteca Underscore.js .

Tenga en cuenta que _.pick() y _.omit() devuelven una copia del objeto y no modifican directamente el objeto original. Asignar el resultado al objeto original debe hacer el truco (no se muestra).

Referencia: link _.pick (objeto, * claves)

Devuelva una copia del objeto, filtrada para que solo tenga valores para las claves en lista blanca (o matriz de claves válidas).

var myJSONObject = 
{"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};

_.pick(myJSONObject, "ircEvent", "method");
=> {"ircEvent": "PRIVMSG", "method": "newURI"};

Referencia: link _.omit (objeto, * claves)

Devuelva una copia del objeto, filtrada para omitir las claves de la lista negra (o la matriz de claves).

var myJSONObject = 
{"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};

_.omit(myJSONObject, "regex");
=> {"ircEvent": "PRIVMSG", "method": "newURI"};

Para matrices, _.filter() y _.reject() se pueden utilizar de una manera similar.


Prueba esto

delete myObject['key'];

Actualización 2018-07-21: Durante mucho tiempo, me he sentido avergonzado por esta respuesta, así que creo que es hora de retocarla un poco. Solo un pequeño comentario, aclaración y formato para ayudar a acelerar la lectura de las partes innecesariamente largas y complicadas de esta respuesta.

LA CORTA VERSION

La respuesta real a la pregunta.

Como otros han dicho, puede utilizar delete .

obj // {"foo": "bar"}
delete obj["foo"]
obj // {}
obj["foo"] // undefined

Array equivalente

No delete de una matriz. Utilice Array.prototype.splice lugar.

arr // [1,2,3,4,5]
arr.splice(3,1); // 4
arr // [1,2,3,5]

LA VERSIÓN LARGA

JavaScript es un lenguaje OOP, por lo que todo es un objeto, incluidas las matrices . Por lo tanto, siento que es necesario señalar una advertencia en particular.

En los arreglos, a diferencia de los objetos antiguos, el uso de delete deja atrás la basura en forma de null , creando un "agujero" en el arreglo.

var array = [1, 2, 3, 4];
delete array[2];
/* Expected result --> [1, 2, 4]
 * Actual result   --> [1, 2, null, 4]
 */

Como puede ver, delete no siempre funciona como uno podría esperar. El valor se sobrescribe, pero la memoria no se reasigna. Es decir, la array[4] no se reubica en la array[3] . Lo que contrasta con Array.prototype.unshift , que inserta un elemento al principio de la matriz y lo desplaza todo hacia arriba (la array[0] convierte en array[1] , etc.)

Honestamente, aparte de establecer en null lugar de undefined es legítimamente extraño), este comportamiento no debería ser sorprendente, ya que delete es un operador unario, como typeof , que está inscrito en el lenguaje y no debe importarle. sobre el tipo de objeto en el que se está utilizando, mientras que Array es una subclase de Object con métodos diseñados específicamente para trabajar con matrices. Así que no hay una buena razón para delete un caso especial preparado para volver a cambiar la matriz, ya que eso solo ralentizaría las cosas con un trabajo innecesario. En retrospectiva, mis expectativas no eran realistas.

Por supuesto, me sorprendió. Porque escribí esto para justificar mi cruzada contra "basura nula":

Ignorando los peligros y problemas inherentes a la null y el espacio desperdiciado, esto puede ser problemático si la matriz necesita ser precisa.

Lo que es una terrible justificación para deshacerse de la null s-- null solo es peligrosa si se usa incorrectamente, y no tiene nada que ver con la "precisión". La verdadera razón por la que no debe delete de una matriz es que dejar las estructuras de datos desordenadas y llenas de basura es descuidado y propenso a errores.

Lo que sigue es un escenario artificial que se torna bastante largo, por lo que puede saltar a la sección, La Solución , si lo desea. La única razón por la que dejo esta sección es porque creo que algunas personas probablemente piensan que es gracioso, y no quiero ser "ese tipo" que publica una respuesta "graciosa" y luego borra todo lo "gracioso" más adelante. .

... Es estúpido, lo sé.

El escenario PDP-11 ideado y de largo aliento

Por ejemplo, supongamos que está creando una aplicación web que utiliza la serialización JSON para almacenar una matriz utilizada para "pestañas" en una cadena (en este caso, localStorage ). Digamos también que el código utiliza los índices numéricos de los miembros de la matriz para "titularlos" al dibujar en la pantalla. ¿Por qué haces esto en lugar de simplemente guardar el "título" también? Porque ... razones .

De acuerdo, digamos que está intentando ahorrar memoria a petición de este usuario que ejecuta una minicomputadora PDP-11 desde la década de 1960 que ejecuta UNIX, y escribió su propia impresora de línea basada en Elinks, compatible con JavaScript. navegador porque X11 está fuera de la cuestión .

Dejando de lado cada vez más el estúpido escenario de borde, el uso de delete en dicha matriz resultará en una contaminación null la matriz, y probablemente causará errores en la aplicación más adelante. Y si marca null , directamente salteará los números que resulten en que las pestañas se representen como [1] [2] [4] [5] ...

if (array[index] == null)
    continue;
else
    title = (index + 1).toString();
/* 0 -> "1"
 * 1 -> "2"
 * 2 -> (nothing)
 * 3 -> "4"
 */

Sí, eso definitivamente no es lo que querías.

Ahora, puede mantener un segundo iterador, como j , para incrementar solo cuando se leen valores válidos de la matriz. Pero eso no resolvería exactamente el problema null , y todavía tiene que complacer a ese usuario del troll PDP-11. Por desgracia, su computadora simplemente no tiene suficiente memoria para mantener ese último entero (no pregunte cómo se las arregla para manejar una matriz de ancho variable ...) .

Entonces, él te envía un correo electrónico con ira:

Hey, your webapp broke my browser! I checked my localStorage database after your stupid code made my browser segfault, and this is what I found:

>"tabs:['Hello World', 'foo bar baz', null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, ... ]"

After clearing my precious data, it segfaulted again, and I did a backtrace, and what do I find? WHAT DO I FIND!? YOU USE TOO MANY VARIABLES!

>var i = index;
>var j = 1;

Grr, I am angry now.
-Troll Davidson

Acerca de ahora, estás al final de tu ingenio. Este tipo se ha estado quejando sin parar de su aplicación, y usted quiere decirle que se calle y obtenga una computadora mejor.

La Solución: Array.prototype.splice

Afortunadamente, las matrices tienen un método especializado para eliminar índices y reasignar memoria: Array.prototype.splice() . Podrías escribir algo como esto:

Array.prototype.remove = function(index){
  this.splice(index,1);
}
...
array = [1, 2, 3, 4];
array.remove(2);
// Result -> [1, 2, 4]

Y así, ha complacido al Sr. PDP-11. ¡Hurra! (Aun así le regañaría, pero ...)

Array.prototype.splice vs Array.prototype.slice

Creo que es importante señalar la diferencia entre estas dos funciones con nombres similares, ya que ambas son muy útiles.

Array.prototype.splice (inicio, n)

.splice() muta la matriz y devuelve los índices eliminados. La matriz se divide a partir del índice, el start y n elementos se cortan. Si no se especifica n, la matriz completa después del start se corta ( n = array.length - start ).

let a = [5,4,3,2,1];
let chunk = a.splice(2,2);

// a     [5,4,3,2,1]
// start  0 1 2 - -
// n      - - 1 2 -

chunk; // [3,2]
a;     // [5,4,1]

Array.prototype.slice (inicio, final)

.slice() no es destructivo y devuelve una nueva matriz que contiene los índices indicados de start a end . Si no se especifica el end , el comportamiento es el mismo que .splice() ( end = array.length ). El comportamiento es un poco complicado ya que, por alguna razón, end índices de 1 en lugar de 0. No sé por qué lo hace, pero así es. Además, si end <= start , el resultado es una matriz vacía.

let a = [5,4,3,2,1];
let chunks = [
    a.slice(2,0),
    a.slice(2,2),
    a.slice(2,3),
    a.slice(2,5) ];

// a             [5,4,3,2,1]
// start          0 1 2 - -
// end, for...    - - - - -
//   chunks[0]  0 - - - - -   
//   chunks[1]    1 2 - - -
//   chunks[2]    1 2 3 - -
//   chunks[3]    1 2 3 4 5

chunks; // [ [], [], [3], [3,2,1] ]
a;      // [5,4,3,2,1]

Eso en realidad no es lo que está sucediendo, pero es más fácil pensar de esa manera. Según MDN, esto es lo que realmente está sucediendo:

// a             [5,4,3,2,1]
// start          0 1 2 - - -
// end, for...    - - - - - -
//   chunks[0]    0 - - - - -
//   chunks[1]    0 1 2 - - -
//   chunks[2]    0 1(2)3 - -
//   chunks[3]    0 1(2 3 4)5

El índice especificado por end es simplemente excluido de la porción. Los índices entre paréntesis indican lo que se corta. De cualquier manera, el comportamiento no es intuitivo y está obligado a causar su parte justa de errores off-by-one, por lo que puede encontrar útil hacer una función de envoltorio para emular más estrechamente el comportamiento de .splice() :

function ez_slice(array, start = 0, n = null){
    if(!Array.isArray(array) || !is_number(start))
        return null;

    if(is_number(n))
        return array.slice(start, start + n);

    if(n === null)
        return array.slice(start);

    return null;
}

ez_slice([5,4,3,2,1], 2, 1) // [3]
ez_slice([5,4,3,2,1], 2)    // [3,2,1]

/* Fun fact: isNaN is unreliable.
 * [NaN, [], {}, 0, 1, Infinity, undefined, null, "Hi"].filter(isNaN)
 * [NaN, {}, undefined, "Hi"]
 *
 * What we want is...
 *
 * [NaN, [], {}, 0, 1, Infinity, undefined, null, "Hi"].filter(is_nan)
 * [NaN]
 */
function is_nan(num){
    return typeof num === "number"
        && num !== num;
}

function is_number(num){
    return !is_nan(num)
        && typeof num === "number"
        && isFinite(num);
}

Tenga en cuenta que la función de envoltura está diseñada para ser muy estricta con respecto a los tipos, y devolverá el null si algo está desactivado. Eso incluye poner una cadena como "3" . Se deja al programador ser diligente sobre sus tipos. Esto es para fomentar la buena práctica de programación.

Actualización sobre is_array()

Esto es con respecto a este fragmento (ahora eliminado):

function is_array(array){
    return array !== null
        && typeof array === "object"
        && typeof array.length !== "undefined"
        && array.__proto__ === Array.prototype;
}

Entonces, resulta que, de hecho, existe una forma integrada de saber si una matriz es realmente una matriz, y esa es Array.isArray() , introducida en ECMAScript 5 (diciembre de 2009). Encontré esto mientras miraba para ver si había una pregunta que preguntaba acerca de cómo contar arrays de objetos, para ver si había una solución mejor que la mía, o para agregar la mía si no había ninguna. Por lo tanto, si está utilizando una versión de JavaScript anterior a ECMA 5, aquí está su polyfill. Sin embargo, recomiendo encarecidamente que no utilice mi función is_array() , ya que continuar is_array() versiones antiguas de JavaScript significa seguir is_array() los navegadores antiguos que las implementan, lo que significa fomentar el uso de software inseguro y poner a los usuarios en riesgo de malware. Así que por favor, use Array.isArray() . Usa let y const . Utiliza las nuevas funciones que se añaden al lenguaje. No utilice prefijos de proveedores. Eliminar esa basura de polietileno de IE de su sitio web. Elimine ese XHTML <!CDATA[[... también, nos mudamos a HTML5 en 2014. Cuanto antes todos retiren el soporte para esos navegadores antiguos / esotéricos, más pronto los proveedores de navegadores seguirán el estándar web y adoptarán el estándar Nueva tecnología, y cuanto antes podamos pasar a una web más segura.


Esta publicación es muy antigua y me parece muy útil, así que decidí compartir la función de desarmar que escribí en caso de que alguien más vea esta publicación y piense por qué no es tan simple como en la función de desarmar de PHP.

La razón para escribir esta nueva unsetfunción es mantener el índice de todas las demás variables en este hash_map. Mire el siguiente ejemplo y vea cómo el índice de "test2" no cambió después de eliminar un valor de hash_map.

function unset(unsetKey, unsetArr, resort){
  var tempArr = unsetArr;
  var unsetArr = {};
  delete tempArr[unsetKey];
  if(resort){
    j = -1;
  }
  for(i in tempArr){
    if(typeof(tempArr[i]) !== 'undefined'){
      if(resort){
        j++;
      }else{
        j = i;
      }
      unsetArr[j] = tempArr[i];
    }
  }
  return unsetArr;
}

var unsetArr = ['test','deletedString','test2'];

console.log(unset('1',unsetArr,true)); // output Object {0: "test", 1: "test2"}
console.log(unset('1',unsetArr,false)); // output Object {0: "test", 2: "test2"}

Hola puedes probar este sencillo y ordenado

var obj = [];

obj.key1 = {name: "John", room: 1234};
obj.key2 = {name: "Jim", room: 1234};

delete(obj.key1);

Muy simple:

var myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI",
    "regex": "^http://.*"
};

delete myObject.regex;

Supongamos que tienes un objeto que se parece a esto:

var Hogwarts = {
    staff : [
        'Argus Filch',
        'Filius Flitwick',
        'Gilderoy Lockhart',
        'Minerva McGonagall',
        'Poppy Pomfrey',
        ...
    ],
    students : [
        'Hannah Abbott',
        'Katie Bell',
        'Susan Bones',
        'Terry Boot',
        'Lavender Brown',
        ...
    ]
};

Eliminar una propiedad de objeto

Si desea utilizar la staffmatriz completa , la forma correcta de hacerlo sería hacer esto:

delete Hogwarts.staff;

Alternativamente, también puedes hacer esto:

delete Hogwarts['staff'];

Del mismo modo, la eliminación de toda la matriz de estudiantes se haría llamando delete Hogwarts.students;odelete Hogwarts['students']; .

Eliminar un índice de matriz

Ahora, si desea eliminar a un solo miembro del personal o estudiante, el procedimiento es un poco diferente, porque ambas propiedades son matrices en sí mismas.

Si conoce el índice de su miembro del personal, simplemente puede hacer esto:

Hogwarts.staff.splice(3, 1);

Si no conoce el índice, también tendrá que hacer una búsqueda de índice:

Hogwarts.staff.splice(Hogwarts.staff.indexOf('Minerva McGonnagall') - 1, 1);

Nota

Si bien técnicamente puede usarlo deletepara una matriz, usarlo resultaría en obtener resultados incorrectos cuando llame Hogwarts.staff.lengthmás adelante, por ejemplo . En otras palabras, deleteeliminaría el elemento, pero no actualizaría el valor de la lengthpropiedad. Usar deletetambién arruinaría tu indexación.

Por lo tanto, cuando elimine valores de un objeto, siempre considere primero si está tratando con las propiedades del objeto o si está tratando con valores de matriz, y elija la estrategia adecuada en función de eso.

Si quieres experimentar con esto, puedes usar este Fiddle como punto de partida.


Usando lodash

import omit from 'lodash/omit';

const prevObject = {test: false, test2: true};
// Removes test2 key from previous object
const nextObject = omit(prevObject, 'test2');

Usando Ramda

R.omit(['a', 'd'], {a: 1, b: 2, c: 3, d: 4}); //=> {b: 2, c: 3}

var myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
    
delete myObject.regex;

console.log ( myObject.regex); // logs: undefined

Esto funciona en Firefox e Internet Explorer, y creo que funciona en todos los demás.


const myObject = {
        "ircEvent": "PRIVMSG",
        "method": "newURI",
        "regex": "^http://.*"
    };

const { regex, ...other } = myObject;

console.log(myObject)
console.log(regex)
console.log(other)


ECMAScript 2015 (o ES6) vino con el objeto Reflect incorporado . Es posible eliminar la propiedad del objeto llamando a la función Reflect.deleteProperty() con el objeto de destino y la clave de propiedad como parámetros:

Reflect.deleteProperty(myJSONObject, 'regex');

que es equivalente a:

delete myJSONObject['regex'];

Pero si la propiedad del objeto no es configurable, no se puede eliminar ni con la función deleteProperty ni con el operador de eliminación:

let obj = Object.freeze({ prop: "value" });
let success = Reflect.deleteProperty(obj, "prop");
console.log(success); // false
console.log(obj.prop); // value

Object.freeze() hace que todas las propiedades del objeto no sean configurables (además de otras cosas). deletePropertyLa función (así como el developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ) devuelve falsecuando intenta eliminar cualquiera de sus propiedades. Si la propiedad es configurable, devuelve true, incluso si la propiedad no existe.

La diferencia entre deletey deletePropertyes cuando se usa el modo estricto:

"use strict";

let obj = Object.freeze({ prop: "value" });
Reflect.deleteProperty(obj, "prop"); // false
delete obj["prop"];
// TypeError: property "prop" is non-configurable and can't be deleted


Otra solución, utilizando Array#reduce.

var myObject = {
  "ircEvent": "PRIVMSG",
  "method": "newURI",
  "regex": "^http://.*"
};

myObject = Object.keys(myObject).reduce(function(obj, key) {
  if (key != "regex") {           //key you want to remove
    obj[key] = myObject[key];
  }
  return obj;
}, {});

console.log(myObject);

Sin embargo, va a mutar el objeto original. Si desea crear un nuevo objeto sin la clave especificada, simplemente asigne la función de reducción a una nueva variable, por ejemplo:

(ES6)

const myObject = {
  ircEvent: 'PRIVMSG',
  method: 'newURI',
  regex: '^http://.*',
};

const myNewObject = Object.keys(myObject).reduce((obj, key) => {
  key !== 'regex' ? obj[key] = myObject[key] : null;
  return obj;
}, {});

console.log(myNewObject);


Personalmente uso Underscore.js para la manipulación de objetos y matrices:

myObject = _.omit(myObject, 'regex');

Simplemente puede eliminar cualquier propiedad de un objeto usando la deletepalabra clave.

Por ejemplo:

var obj = {key1:"val1",key2:"val2",key3:"val3"}

Para eliminar cualquier propiedad, digamos key1, use la deletepalabra clave como esta:

delete obj.key1

O también puedes usar una notación similar a una matriz:

delete obj[key1]

Ref: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… .


Usando ramda#dissoc obtendrá un nuevo objeto sin el atributo regex:

const newObject = R.dissoc('regex', myObject);
// newObject !== myObject

También puede usar otras funciones para lograr el mismo efecto: omitir, seleccionar, ...





object-properties