Deleting Objects in JavaScript - javascript

I'm a bit confused with JavaScript's delete operator. Take the following piece of code:
var obj = {
helloText: "Hello World!"
};
var foo = obj;
delete obj;
After this piece of code has been executed, obj is null, but foo still refers to an object exactly like obj. I'm guessing this object is the same object that foo pointed to.
This confuses me, because I expected that writing delete obj deleted the object that obj was pointing to in memory—not just the variable obj.
Is this because JavaScript's Garbage Collector is working on a retain/release basis, so that if I didn't have any other variables pointing to the object, it would be removed from memory?
(By the way, my testing was done in Safari 4.)

The delete operator deletes only a reference, never an object itself. If it did delete the object itself, other remaining references would be dangling, like a C++ delete. (And accessing one of them would cause a crash. To make them all turn null would mean having extra work when deleting or extra memory for each object.)
Since Javascript is garbage collected, you don't need to delete objects themselves - they will be removed when there is no way to refer to them anymore.
It can be useful to delete references to an object if you are finished with them, because this gives the garbage collector more information about what is able to be reclaimed. If references remain to a large object, this can cause it to be unreclaimed - even if the rest of your program doesn't actually use that object.

The delete command has no effect on regular variables, only properties. After the delete command the property doesn't have the value null, it doesn't exist at all.
If the property is an object reference, the delete command deletes the property but not the object. The garbage collector will take care of the object if it has no other references to it.
Example:
var x = new Object();
x.y = 42;
alert(x.y); // shows '42'
delete x; // no effect
alert(x.y); // still shows '42'
delete x.y; // deletes the property
alert(x.y); // shows 'undefined'
(Tested in Firefox.)

"variables declared implicitly" are properties of the global object, so delete works on them like it works on any property. Variables declared with var are indestructible.

Coming from the Mozilla Documentation, "You can use the delete operator to delete variables declared implicitly but not those declared with the var statement. "
Here is the link: https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference:Operators:Special_Operators:delete_Operator

delete is not used for deleting an object in java Script.
delete used for removing an object key in your case
var obj = { helloText: "Hello World!" };
var foo = obj;
delete obj;
object is not deleted check obj still take same values delete usage:
delete obj.helloText
and then check obj, foo, both are empty object.

Setting a variable to null makes sure to break any references to objects in all browsers including circular references being made between the DOM elements and Javascript scopes. By using delete command we are marking objects to be cleared on the next run of the Garbage collection, but if there are multiple variables referencing the same object, deleting a single variable WILL NOT free the object, it will just remove the linkage between that variable and the object. And on the next run of the Garbage collection, only the variable will be cleaned.

Just found a jsperf you may consider interesting in light of this matter. (it could be handy to keep it around to complete the picture)
It compares delete, setting null and setting undefined.
But keep in mind that it tests the case when you delete/set property many times.

Aside from the GC questions, for performance one should consider the optimizations that the browser may be doing in the background ->
http://coding.smashingmagazine.com/2012/11/05/writing-fast-memory-efficient-javascript/
It appears it may be better to null the reference than to delete it as that may change the behind-the-scenes 'class' Chrome uses.

IE 5 through 8 has a bug where using delete on properties of a host object (Window, Global, DOM etc) throws TypeError "object does not support this action".
var el=document.getElementById("anElementId");
el.foo = {bar:"baz"};
try{
delete el.foo;
}catch(){
//alert("Curses, drats and double double damn!");
el.foo=undefined; // a work around
}
Later if you need to check where the property has a meaning full value use el.foo !== undefined because "foo" in el
will always return true in IE.
If you really need the property to really disappear...
function hostProxy(host){
if(host===null || host===undefined) return host;
if(!"_hostProxy" in host){
host._hostproxy={_host:host,prototype:host};
}
return host._hostproxy;
}
var el=hostProxy(document.getElementById("anElementId"));
el.foo = {bar:"baz"};
delete el.foo; // removing property if a non-host object
if your need to use the host object with host api...
el.parent.removeChild(el._host);

I stumbled across this article in my search for this same answer. What I ended up doing is just popping out obj.pop() all the stored values/objects in my object so I could reuse the object. Not sure if this is bad practice or not. This technique came in handy for me testing my code in Chrome Dev tools or FireFox Web Console.

This work for me, although its not a good practice. It simply delete all the
the associated element with which the object belong.
for (element in homeService) {
delete homeService[element];
}

The delete operator deletes an object, an object's property, or an element from an array. The operator can also delete variables which are not declared with the var statement.
In the example below, 'fruits' is an array declared as a var and is deleted (really??)
delete objectName
delete objectName.property
delete objectName[index]
delete property // The command acts only within a with statement.
var fruits = new Array("Orange", "Apple", "Banana", "Chery");
var newParagraph = document.createElement("p");
var newText = document.createTextNode("Fruits List : " + fruits);
newParagraph.appendChild(newText);
document.body.appendChild(newParagraph);
//Delete the array object.
delete fruits;
var newParagraph1 = document.createElement("p");
var newText1 = document.createTextNode("Display the Fruits after delete the array object - Fruits List : "+ fruits;);
newParagraph1.appendChild(newText1);
document.body.appendChild(newParagraph1);
https://www.w3resource.com/javascript/operators/delete.php

We have multiple ways to Delete the Object property.
Arrow Function: We can also use the arrow function to remove the property from an object which is a one-liner solution.
const obj = {
'first': 'one',
'second': 'two',
'third': 'three'
}
const fn = (key, { [key]: deletedKey, ...others }) => others;
console.log(fn('first', obj)) // { 'second': 'two', 'third': 'three' }
Reduce Method: We can use the reduce method to delete the specific property from the original object in javascript.
const obj = {
'first': 'one',
'second': 'two',
'third': 'three'
}
const exceptSecond = Object.keys(obj).reduce((acc, key) => {
if (key !== 'second') {
acc[key] = obj[key]
}
return acc
}, {})
console.log(exceptSecond) // { 'first': 'one', 'third': 'three' }
Delete: This is easy simple way to delete.
delete obj.first;
// Or
delete obj['first'];
Using unset, Omit, Pic Method from "loadash" lib:
import { unset } from 'lodash'
const obj = {
'first': 'one',
'second': 'two',
'third': 'three'
}
unset(obj, 'third') // true
console.log(obj) // { 'first': 'one', 'second': 'two' }
// Using omit
import { omit } from 'lodash'
const obj1 = {
'first': 'one',
'second': 'two',
'third': 'three'
}
omit(obj1, [ 'first', 'second' ])
console.log(obj1)
Reflect Delete Property: This is the new built-in Object introduced in ES6. Now it is possible to delete object property by calling the deleted property() function from this Refect Object.
This function is equivalent to what we have discussed with the delete operator in the first method.
const someObject = {
'first': 'one',
'second': 'two',
'third': 'three'
}
Reflect.deleteProperty(someObject, 'second')
console.log(someObject) // { 'first': 'one', 'third': 'three' }

If you want the object to be deleted based on its value do this:
Object.keys(obj).forEach((key) => {
if (obj[key] === "Hello World!") {
delete obj[key];
}
});
But deleting an object is not a good idea. So, set it to undefined, so that when you pass it to a parameter. It won't be showing. No need to delete.
Object.keys(obj).forEach((key) => {
if (obj[key] === "Hello World!") {
obj[key] = undefined;
}
});

Related

How to delete object oriented function in java script [duplicate]

I'm a bit confused with JavaScript's delete operator. Take the following piece of code:
var obj = {
helloText: "Hello World!"
};
var foo = obj;
delete obj;
After this piece of code has been executed, obj is null, but foo still refers to an object exactly like obj. I'm guessing this object is the same object that foo pointed to.
This confuses me, because I expected that writing delete obj deleted the object that obj was pointing to in memory—not just the variable obj.
Is this because JavaScript's Garbage Collector is working on a retain/release basis, so that if I didn't have any other variables pointing to the object, it would be removed from memory?
(By the way, my testing was done in Safari 4.)
The delete operator deletes only a reference, never an object itself. If it did delete the object itself, other remaining references would be dangling, like a C++ delete. (And accessing one of them would cause a crash. To make them all turn null would mean having extra work when deleting or extra memory for each object.)
Since Javascript is garbage collected, you don't need to delete objects themselves - they will be removed when there is no way to refer to them anymore.
It can be useful to delete references to an object if you are finished with them, because this gives the garbage collector more information about what is able to be reclaimed. If references remain to a large object, this can cause it to be unreclaimed - even if the rest of your program doesn't actually use that object.
The delete command has no effect on regular variables, only properties. After the delete command the property doesn't have the value null, it doesn't exist at all.
If the property is an object reference, the delete command deletes the property but not the object. The garbage collector will take care of the object if it has no other references to it.
Example:
var x = new Object();
x.y = 42;
alert(x.y); // shows '42'
delete x; // no effect
alert(x.y); // still shows '42'
delete x.y; // deletes the property
alert(x.y); // shows 'undefined'
(Tested in Firefox.)
"variables declared implicitly" are properties of the global object, so delete works on them like it works on any property. Variables declared with var are indestructible.
Coming from the Mozilla Documentation, "You can use the delete operator to delete variables declared implicitly but not those declared with the var statement. "
Here is the link: https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference:Operators:Special_Operators:delete_Operator
delete is not used for deleting an object in java Script.
delete used for removing an object key in your case
var obj = { helloText: "Hello World!" };
var foo = obj;
delete obj;
object is not deleted check obj still take same values delete usage:
delete obj.helloText
and then check obj, foo, both are empty object.
Setting a variable to null makes sure to break any references to objects in all browsers including circular references being made between the DOM elements and Javascript scopes. By using delete command we are marking objects to be cleared on the next run of the Garbage collection, but if there are multiple variables referencing the same object, deleting a single variable WILL NOT free the object, it will just remove the linkage between that variable and the object. And on the next run of the Garbage collection, only the variable will be cleaned.
Just found a jsperf you may consider interesting in light of this matter. (it could be handy to keep it around to complete the picture)
It compares delete, setting null and setting undefined.
But keep in mind that it tests the case when you delete/set property many times.
Aside from the GC questions, for performance one should consider the optimizations that the browser may be doing in the background ->
http://coding.smashingmagazine.com/2012/11/05/writing-fast-memory-efficient-javascript/
It appears it may be better to null the reference than to delete it as that may change the behind-the-scenes 'class' Chrome uses.
IE 5 through 8 has a bug where using delete on properties of a host object (Window, Global, DOM etc) throws TypeError "object does not support this action".
var el=document.getElementById("anElementId");
el.foo = {bar:"baz"};
try{
delete el.foo;
}catch(){
//alert("Curses, drats and double double damn!");
el.foo=undefined; // a work around
}
Later if you need to check where the property has a meaning full value use el.foo !== undefined because "foo" in el
will always return true in IE.
If you really need the property to really disappear...
function hostProxy(host){
if(host===null || host===undefined) return host;
if(!"_hostProxy" in host){
host._hostproxy={_host:host,prototype:host};
}
return host._hostproxy;
}
var el=hostProxy(document.getElementById("anElementId"));
el.foo = {bar:"baz"};
delete el.foo; // removing property if a non-host object
if your need to use the host object with host api...
el.parent.removeChild(el._host);
I stumbled across this article in my search for this same answer. What I ended up doing is just popping out obj.pop() all the stored values/objects in my object so I could reuse the object. Not sure if this is bad practice or not. This technique came in handy for me testing my code in Chrome Dev tools or FireFox Web Console.
This work for me, although its not a good practice. It simply delete all the
the associated element with which the object belong.
for (element in homeService) {
delete homeService[element];
}
The delete operator deletes an object, an object's property, or an element from an array. The operator can also delete variables which are not declared with the var statement.
In the example below, 'fruits' is an array declared as a var and is deleted (really??)
delete objectName
delete objectName.property
delete objectName[index]
delete property // The command acts only within a with statement.
var fruits = new Array("Orange", "Apple", "Banana", "Chery");
var newParagraph = document.createElement("p");
var newText = document.createTextNode("Fruits List : " + fruits);
newParagraph.appendChild(newText);
document.body.appendChild(newParagraph);
//Delete the array object.
delete fruits;
var newParagraph1 = document.createElement("p");
var newText1 = document.createTextNode("Display the Fruits after delete the array object - Fruits List : "+ fruits;);
newParagraph1.appendChild(newText1);
document.body.appendChild(newParagraph1);
https://www.w3resource.com/javascript/operators/delete.php
We have multiple ways to Delete the Object property.
Arrow Function: We can also use the arrow function to remove the property from an object which is a one-liner solution.
const obj = {
'first': 'one',
'second': 'two',
'third': 'three'
}
const fn = (key, { [key]: deletedKey, ...others }) => others;
console.log(fn('first', obj)) // { 'second': 'two', 'third': 'three' }
Reduce Method: We can use the reduce method to delete the specific property from the original object in javascript.
const obj = {
'first': 'one',
'second': 'two',
'third': 'three'
}
const exceptSecond = Object.keys(obj).reduce((acc, key) => {
if (key !== 'second') {
acc[key] = obj[key]
}
return acc
}, {})
console.log(exceptSecond) // { 'first': 'one', 'third': 'three' }
Delete: This is easy simple way to delete.
delete obj.first;
// Or
delete obj['first'];
Using unset, Omit, Pic Method from "loadash" lib:
import { unset } from 'lodash'
const obj = {
'first': 'one',
'second': 'two',
'third': 'three'
}
unset(obj, 'third') // true
console.log(obj) // { 'first': 'one', 'second': 'two' }
// Using omit
import { omit } from 'lodash'
const obj1 = {
'first': 'one',
'second': 'two',
'third': 'three'
}
omit(obj1, [ 'first', 'second' ])
console.log(obj1)
Reflect Delete Property: This is the new built-in Object introduced in ES6. Now it is possible to delete object property by calling the deleted property() function from this Refect Object.
This function is equivalent to what we have discussed with the delete operator in the first method.
const someObject = {
'first': 'one',
'second': 'two',
'third': 'three'
}
Reflect.deleteProperty(someObject, 'second')
console.log(someObject) // { 'first': 'one', 'third': 'three' }
If you want the object to be deleted based on its value do this:
Object.keys(obj).forEach((key) => {
if (obj[key] === "Hello World!") {
delete obj[key];
}
});
But deleting an object is not a good idea. So, set it to undefined, so that when you pass it to a parameter. It won't be showing. No need to delete.
Object.keys(obj).forEach((key) => {
if (obj[key] === "Hello World!") {
obj[key] = undefined;
}
});

ES6 dispose of the object destructuring left-over (object trimming)

One nice use-case of the destructuring feature when used with rest parameters is that you can get trimmed clones.
var source = { w1: 'val1', w2: 'val2', unwanted1: 'val3', unwanted2: 'val4'};
var {unwanted1, unwanted2, ...target} = source;
console.log(target); // `{ w1: 'val1', w2: 'val2' }` Exactly what you want
However, the side effect is that your scope is now polluted with two variables that you never care to use: unwanted1 and unwanted2.
If _ meant don't care, you could do something like this
var {
unwanted1:_, // throw away
unwanted2:_, // throw away
target
} = source;
However, in Javascript _ is a proper identifier.
If used once in that manner (unwanted: _), you'll end up with one unwanted variable called _, which goes against the goal.
If used more than once, like above, an error is issued:
SyntaxError: Identifier '_' has already been declared.
Is there any way I can throw away the undesired artifacts/variables of destructuring?
Of course, the following solutions are always available.
var target = {
w1: source.w1,
w2: source.w2,
}
and
var target = {...source};
delete target.unwanted1;
delete target.unwanted2;
However doing this with destructuring only seems to be the cleanest way if you're cloning an object with many parameters and you need to exclude just a couple.
Introducing _, __, ___, etc to drop 1,2,3 or more properties doesn't make much difference as it still creates the variables, which '...you will never care to use' and moreover, it threatens to add a flavor of spaghetti to your code.
However, since you need to indicate explicitly which exactly properties you want to drop, one may consider other object trimming techniques, e.g.
filter unwanted properties
const obj = {prop1: 1, prop2:2, prop3: 3, prop4: 4, prop5: 5},
keysToDrop = ['prop2', 'prop3', 'prop4'],
trimmedObj = Object.fromEntries(
Object
.entries(obj)
.filter(([key,val]) => !keysToDrop.includes(key)
)
)
console.log(trimmedObj)
.as-console-wrapper{min-height:100%;}
make use of Array.prototype.reduce(), which may even give you certain performance boost, compared to destructuring
const obj = {prop1: 1, prop2:2, prop3: 3, prop4: 4, prop5: 5},
keysToDrop = ['prop2', 'prop3', 'prop4'],
trimmedObj = Object
.keys(obj)
.reduce((r,key) =>
(!keysToDrop.includes(key) && (r[key] = obj[key]), r),{})
console.log(trimmedObj)
.as-console-wrapper{min-height:100%;}
Use _, __,___ or Just method to exclude: :D haha
function prop(source, excluded) {
if (source == null) return {};
var target = {};
var sourceKeys = Object.keys(source);
var key, i;
for (i = 0; i < sourceKeys.length; i++) {
key = sourceKeys[i];
if (excluded.indexOf(key) >= 0) continue;
target[key] = source[key];
}
return target;
}
var source = {
w1: "val1",
w2: "val2",
unwanted1: "val3",
unwanted2: "val4"
};
var target = prop(source, ["unwanted1", "unwanted2"]);
Is there any way I can throw away the undesired artifacts/variables of destructuring?
The only way that's also not too terrible would be to define a function that does the same thing:
const clone = ({unwanted1, unwanted2, ...target}) => target;
const target = clone(source);
The variables are still created but their visibility is limited to the function which terminates immediately.
However doing this with destructuring only seems to be the cleanest way if you're cloning an object with many parameters and you need to exclude just a couple.
The disadvantage of the above approach is that the function is specific to a specific object. You cannot reuse it for other objects. Sure, it's rather small so maybe that's not a big deal. But having a more generic helper function might be easier to understand.

How to grab the children of an Object.keys(myEl) reference

In the code below, I can get a reference to the text000 object, but I need to capture its child array as my target payload. Once I have a reference to the key, how can I capture its children?
Full object is below:
activeItem = [{"dnd":{"index":0,"active":true,"group":"common","label":"Text (000)","type":"text"},
"json":{"schema":{"properties":{"text000":{"title":"Text (000)","type":"string"}},"required":["text000"]},"layout":[{"key":"text000","description":"","floatLabel":"auto","validationMessages":{"required":"Required"}}]}}]
To grab a reference to the "text000" key I'm using:
const myEl = Object.keys(this.activeItem.json.schema.properties); // points to text000
I need to pull that key's contents/children > {"title":"Text (000)","type":"string"} out to use it as my target payload for this operation.
The text000 element is dynamic so I need its reference, which is why I'm using the Object.keys() method to point to it.
Feel free to school me on the proper names to use to refer to these elements. For example, not sure exactly how to reference > {"title":"Text (000)","type":"string"} with respect to the key text000. Is that the key's "children", "value", "contents" or what?
UPDATE:
console.log('TRY: ', this.activeItem.json.schema.properties[0]);
// Returns undefined
console.log('TRY2: ', this.activeItem.json.schema.properties);
// Returns {"text000":{"title":"Text (000)","type":"string"}}
I need something to return:
{"title":"Text (000)","type":"string"}
SOLUTION thanks #jaredgorski:
const properties = this.activeItem.json.schema.properties;
const propertiesKeys = Object.keys(properties);
const propertiesKeysFirstVal = Object.keys(properties)[0];
const logProperties = properties[propertiesKeysFirstVal];
console.log('PROPERTIES KEYS:', propertiesKeys);
console.log(
'VALUES OF FIRST PROPERTIES KEY:',
propertiesKeysFirstVal
);
console.log('RESULT:', logProperties);
PROPERTIES KEYS: ["text000"]
wrux-wrux-form-builder.js:1782 VALUES OF FIRST PROPERTIES KEY: text000
wrux-wrux-form-builder.js:1783 RESULT: {title: "Text (000)", type: "string"}
You need to remember that activeItem is an array. As long as you include the index (in this case the first index, which is [0]), you can access the json property (or key) and continue down the chain to retrieve the values in text000.
The other trick here is that you're wanting to access the first key in properties, but you don't know the name of that key yet. So what you need to do is actually make an array of the keys and then find out the name of the first key in that properties object. To do this, you can use Object.keys(), a method which turns the keys of an object into an array. Once you have the name of this key, you only need to use bracket notation on the properties object to find the value for this key. I'll show you how this works in the snippet below.
Here are some references so that you can learn more about how this works:
MDN page on the Object.keys() method
Accessing JavaScript
object properties: Bracket notation vs. Dot notation
And here's the working example:
const activeItem = [
{
"dnd": {
"index": 0,
"active": true,
"group":"common",
"label":"Text (000)",
"type":"text",
"icon":"text_fields",
"fontSet":"material-icons",
"class":""
},
"json": {
"schema": {
"properties": {
"text000":{
"title":"Text (000)",
"type":"string"
}
},
"required":["text000"]
},
"layout":[
{
"key":"text000",
"description":"",
"floatLabel":"auto",
"validationMessages": {
"required":"Required"
}
}
]
}
}
]
// This is the dirty looking version:
const logPropertiesDirty = activeItem[0].json.schema.properties[Object.keys(activeItem[0].json.schema.properties)[0]]
console.log("First, the dirty version where we don't save anything to variables. Everything is laid out here.")
console.log('WHAT WE DID:', 'activeItem[0].json.schema.properties[Object.keys(activeItem[0].json.schema.properties)[0]]')
console.log('RESULT:', logPropertiesDirty)
console.log('=================================================')
// This is the cleaner version, using variables to store things as we go:
const properties = activeItem[0].json.schema.properties;
const propertiesKeys = Object.keys(properties);
const propertiesKeysFirstVal = Object.keys(properties)[0];
const logPropertiesClean = properties[propertiesKeysFirstVal];
console.log('Now, the cleaner version. We save some values to variables to make things more readable.')
console.log('PROPERTIES OBJECT:', properties)
console.log('PROPERTIES KEYS:', propertiesKeys)
console.log('NAME OF FIRST PROPERTIES KEY:', propertiesKeysFirstVal)
console.log('RESULT:', logPropertiesClean)
Regarding what to call these things, I've always thought of Objects as generally consisting of "key-value pairs". Keys can also be called properties and values can also be called contents (I guess).
myObject = {
key1: value1,
property2: contentsOfProperty2
}
At the end of the day, clear communication is all that counts! So, whatever names you come up with (as long as they make reasonable sense), I'm sure people won't be jerks about it unless they feel like they have something to prove.
You should be able to use Object.values over this.activeItem.json.schema.properties:
The Object.values() method returns an array of a given object's own enumerable property values, in the same order as that provided by a for...in loop (the difference being that a for-in loop enumerates properties in the prototype chain as well).
const object1 = {
a: 'somestring',
b: 42,
c: false
};
console.log(Object.values(object1));
// expected output: Array ["somestring", 42, false]
It is not supported across the map yet, but you should be able to load a polyfill if you need it.

Removing all properties from a object

I have this Javascript object.
req.session
In my code I add properties to this object. These properties can be other objects, arrays, or just plain strings.
req.session.savedDoc = someObject;
req.session.errors = ['someThing', 'anotherThing', 'thirdThing'];
req.session.message = 'someString'
If I later would like to erase all added properties of this object, what is the easiest/best way?
There must be a better way than this?
// Delete all session values
delete req.session.savedDoc;
delete req.session.errors;
delete req.session.message;
#VisioN's answer works if you want to clear that specific reference, but if you actually want to clear an object I found that this works:
for (var variableKey in vartoClear){
if (vartoClear.hasOwnProperty(variableKey)){
delete vartoClear[variableKey];
}
}
There are two possible solutions to the problem:
Assign an empty object
req.session = {};
The garbage collector will clean the memory automatically. This variant is super fast and will work in most cases, however, you need to use it with caution, as it may keep the references to the objects in memory. This caveat is described in the TLDR section below.
Delete properties one-by-one
Object.keys(object).forEach(key => delete object[key]);
This will clean the object by going through every non-prototype property and deleting it. It's safer but slower. You need to decide if it makes sense for you to use it in a particular case.
TLDR
Any solution given above will do the job for the author in the current situation, as well as any other valid solution provided in this question. It mainly depends on the way how the developer wants to manipulate the deprecated data.
Session object may contain data that is linked by different variable, and setting a new empty object to req.session will not break the reference to the old data, so the old data will be available where it is still required. Although the correct way to keep old data is to clone the initial object, real-life scenarios can be different. Let's look at the following example:
req.session.user = { name: "Alexander" }; // we store an object in the session
var session = req.session; // save reference to the session in a variable
console.log( req.session, session ); // {user: Object}, {user: Object}
req.session = {}; // let's replace session with a new object
console.log( req.session, session ); // {}, {user: Object}
We still can fetch old data from session variable but req.session is empty: here setting a new object works as a sort of alternative to deep cloning. The garbage collector will not remove data from the old req.session object as it is still referenced by the session variable.
Deep cleaning of the object with:
Object.keys(object).forEach(key => delete object[key]);
... will explicitly remove all values from the req.session object and, since session variable is linked to the same object, session will become empty as well. Let's see how it works:
req.session.user = { name: "Alexander" }; // we store an object in the session
var session = req.session; // save reference to the session in a variable
console.log( req.session, session ); // {user: Object}, {user: Object}
Object.keys(req.session).forEach(key => delete req.session[key]);
console.log( req.session, session ); // {}, {}
As you can see now, in both cases we get empty objects.
From speed and memory perspectives setting a new empty object will be much faster than cleaning the old object property by property, however memory-wise if the old data is still referenced somewhere, the new object approach won't free up memory that old data is consuming.
It's quite obvious that choosing the approach to take is mostly up to your coding scenario but in most cases req.session = {}; will do the job: it is fast and short. However, if you keep references to the original object in other variables, you may consider using deep implicit object properties deletion.
I can see only one correct solution for removing own properties from object:
for (var x in objectToClean) if (objectToClean.hasOwnProperty(x)) delete objectToClean[x];
If you want to use it more than once, you should create a cleaning function:
function deleteProperties(objectToClean) {
for (var x in objectToClean) if (objectToClean.hasOwnProperty(x)) delete objectToClean[x];
}
For your case the usage would be:
deleteProperties(req.session);
This solution removes properties from the object wherever it's referenced and keeping the old reference.
Example:
Using empty object assignment:
var x = {a: 5};
var y = x;
x = {}; // x will be empty but y is still {a: 5}, also now reference is gone: x !== y
Using cleaning method:
var x = {a: 5};
var y = x;
deleteProperties(x); // x and y are both empty and x === y
If you want to delete all properties without touching methods you can use :
for(var k in req.session) if(!req.session[k].constructor.toString().match(/^function Function\(/)) delete req.session[k];
You can use a map instead if you care about performance like so
const map = new Map()
map.set("first", 1)
map.set("second", 1)
map.clear()
This is a O(1) operation, so even if you have a huge object you do not need to iterate x times to delete the entries.
I've done it like this
var
i,
keys = Object.keys(obj);
for(i = 0; i < keys.length; i++){
delete obj[keys[i]];
}
You could add it to Object (prototype's not ideal here) - will be static.
Object.defineproperties(Object, {
'clear': function(target){
var
i,
keys = Object.keys(target);
for(i = 0; i < keys.length; i++){
delete target[keys[i]];
}
}
});
Then you can clear random objects with
Object.clear(yourObj);
yourObj = {} replaces the reference to a new object, the above removes it's properties - reference is the same.
The naive object = {} method is okay for vanilla Object, but it deletes prototypes of custom objects.
This method produces an empty object that preserves prototypes, using Object.getPrototypeOf() and Object.create():
emptyObj = Object.create(Object.getPrototypeOf(obj), {});
Example:
class Custom extends Object {
custom() {}
}
let custom = new Custom();
custom.foo = "bar";
console.log(custom.constructor.name, custom);
// Custom {"foo": "bar"}
// naive method:
let objVanilla = {}
console.log(objVanilla.constructor.name, objVanilla);
// Object {}
// safe method:
objSafe = Object.create(Object.getPrototypeOf(custom), {});
console.log(objSafe.constructor.name, objSafe);
// Custom {}
This script removes property recursively except for the data reported in vector.
You need the lodash library
-- Function:
function removeKeysExcept(object, keysExcept = [], isFirstLevel = true) {
let arrayKeysExcept = [],
arrayNextKeysExcept = {};
_.forEach(keysExcept, (value, i) => {
let j = value.split('.');
let keyExcept = j[0];
arrayKeysExcept.push(keyExcept);
j.shift();
if (j.length) {
j = j.join('.');
if (!arrayNextKeysExcept[keyExcept]) {
arrayNextKeysExcept[keyExcept] = [];
}
arrayNextKeysExcept[keyExcept].push(j);
}
})
_.forEach(arrayNextKeysExcept, (value, key) => {
removeKeysExcept(object[key], value, false);
});
if (isFirstLevel) {
return;
}
Object.keys(object).forEach(function (key) {
if (arrayKeysExcept.indexOf(key) == -1) {
delete object[key];
}
});
}
Run so:
-- Removes all properties except the first level and reported in the vector:
removeKeysExcept(obj, ['department.id','user.id']);
-- Removes all properties
removeKeysExcept(obj, ['department.id','user.id'], false);
-- Example:
let obj = {
a: {
aa: 1,
ab: {
aba: 21
}
},
b: 10,
c: {
ca: 100,
cb: 200
}
};
removeKeysExcept(obj, ['a.ab.aba','c.ca']);
/*OUTPUT: {
a: {
ab: {
aba: 21
}
},
b: 10,
c: {
ca: 100,
}
};*/
removeKeysExcept(obj, ['a.ab.aba','c.ca'], false); //Remove too firt level
/*OUTPUT: {
a: {
ab: {
aba: 21
}
},
c: {
ca: 100,
}
};*/
removeKeysExcept(obj);
/*OUTPUT: {b:10};*/
removeKeysExcept(obj, [], false); //Remove too firt level
/*OUTPUT: {};*/

How do I remove a property from a JavaScript object?

Given an object:
let myObject = {
"ircEvent": "PRIVMSG",
"method": "newURI",
"regex": "^http://.*"
};
How do I remove the property regex to end up with the following myObject?
let myObject = {
"ircEvent": "PRIVMSG",
"method": "newURI"
};
To remove a property from an object (mutating the object), you can do it like this:
delete myObject.regex;
// or,
delete myObject['regex'];
// or,
var prop = "regex";
delete myObject[prop];
Demo
var myObject = {
"ircEvent": "PRIVMSG",
"method": "newURI",
"regex": "^http://.*"
};
delete myObject.regex;
console.log(myObject);
For anyone interested in reading more about it, Stack Overflow user kangax has written an incredibly in-depth blog post about the delete statement on their blog, Understanding delete. It is highly recommended.
If you'd like a new object with all the keys of the original except some, you could use destructuring.
Demo
let myObject = {
"ircEvent": "PRIVMSG",
"method": "newURI",
"regex": "^http://.*"
};
// assign the key regex to the variable _ indicating it will be unused
const {regex: _, ...newObj} = myObject;
console.log(newObj); // has no 'regex' key
console.log(myObject); // remains unchanged
Objects in JavaScript can be thought of as maps between keys and values. The delete operator is used to remove these keys, more commonly known as object properties, one at a time.
var obj = {
myProperty: 1
}
console.log(obj.hasOwnProperty('myProperty')) // true
delete obj.myProperty
console.log(obj.hasOwnProperty('myProperty')) // false
The delete operator does not directly free memory, and it differs from simply assigning the value of null or undefined to a property, in that the property itself is removed from the object. Note that if the value of a deleted property was a reference type (an object), and another part of your program still holds a reference to that object, then that object will, of course, not be garbage collected until all references to it have disappeared.
delete will only work on properties whose descriptor marks them as configurable.
Old question, modern answer. Using object destructuring, an ECMAScript 6 feature, it's as simple as:
const { a, ...rest } = { a: 1, b: 2, c: 3 };
Or with the questions sample:
const myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
const { regex, ...newObject } = myObject;
console.log(newObject);
You can see it in action in the Babel try-out editor.
Edit:
To reassign to the same variable, use a let:
let myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
({ regex, ...myObject } = myObject);
console.log(myObject);
var myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
delete myObject.regex;
console.log ( myObject.regex); // logs: undefined
This works in Firefox and Internet Explorer, and I think it works in all others.
The delete operator is used to remove properties from objects.
const obj = { foo: "bar" };
delete obj.foo;
obj.hasOwnProperty("foo"); // false
Note that, for arrays, this is not the same as removing an element. To remove an element from an array, use Array#splice or Array#pop. For example:
arr; // [0, 1, 2, 3, 4]
arr.splice(3,1); // 3
arr; // [0, 1, 2, 4]
Details
Strictly speaking, it's impossible to truly delete anything in JavaScript. The delete operator neither deletes objects nor frees memory. Rather, it sets its operand to undefined and manipulates the parent object so that the member is gone.
let parent = {
member: { str: "Hello" }
};
let secondref = parent.member;
delete parent.member;
parent.member; // undefined
secondref; // { str: "Hello" }
The object is not deleted. Only the reference is. Memory is only freed
by the garbage collector when all references to an object are removed.
Another important caveat is that the delete operator will not reorganize structures for you, which has results that can seem counterintuitive. Deleting an array index, for example, will leave a "hole" in it.
let array = [0, 1, 2, 3]; // [0, 1, 2, 3]
delete array[2]; // [0, 1, empty, 3]
This is because arrays are objects. So indices are the same as keys.
let fauxarray = {0: 1, 1: 2, length: 2};
fauxarray.__proto__ = [].__proto__;
fauxarray.push(3);
fauxarray; // [1, 2, 3]
Array.isArray(fauxarray); // false
Array.isArray([1, 2, 3]); // true
Different built-in functions in JavaScript handle arrays with holes in them differently.
for..in statements will skip the empty index completely.
A naive for loop will yield undefined for the value at the index.
Any method using Symbol.iterator will return undefined for the value at the index.
forEach, map and reduce will simply skip the missing index, but will not remove it
Example:
let array = [1, 2, 3]; // [1,2,3]
delete array[1]; // [1, empty, 3]
array.map(x => 0); // [0, empty, 0]
So, the delete operator should not be used for the common use-case of removing elements from an array. Arrays have a dedicated methods for removing elements and reallocating memory: Array#splice() and Array#pop.
Array#splice(start[, deleteCount[, item1[, item2[, ...]]]])
Array#splice mutates the array, and returns any removed indices. deleteCount elements are removed from index start, and item1, item2... itemN are inserted into the array from index start. If deleteCount is omitted then elements from startIndex are removed to the end of the array.
let a = [0,1,2,3,4]
a.splice(2,2) // returns the removed elements [2,3]
// ...and `a` is now [0,1,4]
There is also a similarly named, but different, function on Array.prototype: Array#slice.
Array#slice([begin[, end]])
Array#slice is non-destructive, and returns a new array containing the indicated indices from start to end. If end is left unspecified, it defaults to the end of the array. If end is positive, it specifies the zero-based non-inclusive index to stop at. If end is negative it, it specifies the index to stop at by counting back from the end of the array (eg. -1 will omit the final index). If end <= start, the result is an empty array.
let a = [0,1,2,3,4]
let slices = [
a.slice(0,2),
a.slice(2,2),
a.slice(2,3),
a.slice(2,5) ]
// a [0,1,2,3,4]
// slices[0] [0 1]- - -
// slices[1] - - - - -
// slices[2] - -[3]- -
// slices[3] - -[2 4 5]
Array#pop
Array#pop removes the last element from an array, and returns that element. This operation changes the length of the array. The opposite operation is push
Array#shift
Array#shift is similar to pop, except it removes the first element. The opposite operation is unshift.
Spread Syntax (ES6)
To complete Koen's answer, in case you want to remove a dynamic variable using the spread syntax, you can do it like so:
const key = 'a';
const { [key]: foo, ...rest } = { a: 1, b: 2, c: 3 };
console.log(foo); // 1
console.log(rest); // { b: 2, c: 3 }
* foo will be a new variable with the value of a (which is 1).
Extended answer 😇
There are a few common ways to remove a property from an object. Each one has its own pros and cons (check this performance comparison):
Delete Operator
It is readable and short, however, it might not be the best choice if you are operating on a large number of objects as its performance is not optimized.
delete obj[key];
Reassignment
It is more than two times faster than delete, however the property is not deleted and can be iterated.
obj[key] = null;
obj[key] = false;
obj[key] = undefined;
Spread Operator
This ES6 operator allows us to return a brand new object, excluding any properties, without mutating the existing object. The downside is that it has the worse performance out of the above and is not suggested to be used when you need to remove many properties at a time.
{ [key]: val, ...rest } = obj;
Another alternative is to use the Underscore.js library.
Note that _.pick() and _.omit() both return a copy of the object and don't directly modify the original object. Assigning the result to the original object should do the trick (not shown).
Reference: link _.pick(object, *keys)
Return a copy of the object, filtered to only have values for the
whitelisted keys (or array of valid keys).
var myJSONObject =
{"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
_.pick(myJSONObject, "ircEvent", "method");
=> {"ircEvent": "PRIVMSG", "method": "newURI"};
Reference: link _.omit(object, *keys)
Return a copy of the object, filtered to omit the
blacklisted keys (or array of keys).
var myJSONObject =
{"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
_.omit(myJSONObject, "regex");
=> {"ircEvent": "PRIVMSG", "method": "newURI"};
For arrays, _.filter() and _.reject() can be used in a similar manner.
To clone an object without a property:
For example:
let object = { a: 1, b: 2, c: 3 };
And we need to delete a.
With an explicit prop key:
const { a, ...rest } = object;
object = rest;
With a variable prop key:
const propKey = 'a';
const { [propKey]: propValue, ...rest } = object;
object = rest;
A cool arrow function 😎:
const removeProperty = (propKey, { [propKey]: propValue, ...rest }) => rest;
object = removeProperty('a', object);
For multiple properties
const removeProperties = (object, ...keys) => (keys.length ? removeProperties(removeProperty(keys.pop(), object), ...keys) : object);
Usage
object = removeProperties(object, 'a', 'b') // result => { c: 3 }
Or
const propsToRemove = ['a', 'b']
object = removeProperties(object, ...propsToRemove) // result => { c: 3 }
The term you have used in your question title, Remove a property from a JavaScript object, can be interpreted in some different ways. The one is to remove it for whole the memory and the list of object keys or the other is just to remove it from your object. As it has been mentioned in some other answers, the delete keyword is the main part. Let's say you have your object like:
myJSONObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
If you do:
console.log(Object.keys(myJSONObject));
the result would be:
["ircEvent", "method", "regex"]
You can delete that specific key from your object keys like:
delete myJSONObject["regex"];
Then your objects key using Object.keys(myJSONObject) would be:
["ircEvent", "method"]
But the point is if you care about memory and you want to whole the object gets removed from the memory, it is recommended to set it to null before you delete the key:
myJSONObject["regex"] = null;
delete myJSONObject["regex"];
The other important point here is to be careful about your other references to the same object. For instance, if you create a variable like:
var regex = myJSONObject["regex"];
Or add it as a new pointer to another object like:
var myOtherObject = {};
myOtherObject["regex"] = myJSONObject["regex"];
Then even if you remove it from your object myJSONObject, that specific object won't get deleted from the memory, since the regex variable and myOtherObject["regex"] still have their values. Then how could we remove the object from the memory for sure?
The answer would be to delete all the references you have in your code, pointed to that very object and also not use var statements to create new references to that object. This last point regarding var statements, is one of the most crucial issues that we are usually faced with, because using var statements would prevent the created object from getting removed.
Which means in this case you won't be able to remove that object because you have created the regex variable via a var statement, and if you do:
delete regex; //False
The result would be false, which means that your delete statement haven't been executed as you expected. But if you had not created that variable before, and you only had myOtherObject["regex"] as your last existing reference, you could have done this just by removing it like:
myOtherObject["regex"] = null;
delete myOtherObject["regex"];
In other words, a JavaScript object is eligible to be killed as soon as there is no reference left in your code pointed to that object.
Update:
Thanks to #AgentME:
Setting a property to null before deleting it doesn't accomplish
anything (unless the object has been sealed by Object.seal and the
delete fails. That's not usually the case unless you specifically
try).
To get more information on Object.seal: Object.seal()
ECMAScript 2015 (or ES6) came with built-in Reflect object. It is possible to delete object property by calling Reflect.deleteProperty() function with target object and property key as parameters:
Reflect.deleteProperty(myJSONObject, 'regex');
which is equivalent to:
delete myJSONObject['regex'];
But if the property of the object is not configurable it cannot be deleted neither with deleteProperty function nor delete operator:
let obj = Object.freeze({ prop: "value" });
let success = Reflect.deleteProperty(obj, "prop");
console.log(success); // false
console.log(obj.prop); // value
Object.freeze() makes all properties of object not configurable (besides other things). deleteProperty function (as well as delete operator) returns false when tries to delete any of it's properties. If property is configurable it returns true, even if property does not exist.
The difference between delete and deleteProperty is when using strict mode:
"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
Suppose you have an object that looks like this:
var Hogwarts = {
staff : [
'Argus Filch',
'Filius Flitwick',
'Gilderoy Lockhart',
'Minerva McGonagall',
'Poppy Pomfrey',
...
],
students : [
'Hannah Abbott',
'Katie Bell',
'Susan Bones',
'Terry Boot',
'Lavender Brown',
...
]
};
Deleting an object property
If you want to use the entire staff array, the proper way to do this, would be to do this:
delete Hogwarts.staff;
Alternatively, you could also do this:
delete Hogwarts['staff'];
Similarly, removing the entire students array would be done by calling delete Hogwarts.students; or delete Hogwarts['students'];.
Deleting an array index
Now, if you want to remove a single staff member or student, the procedure is a bit different, because both properties are arrays themselves.
If you know the index of your staff member, you could simply do this:
Hogwarts.staff.splice(3, 1);
If you do not know the index, you'll also have to do an index search:
Hogwarts.staff.splice(Hogwarts.staff.indexOf('Minerva McGonnagall') - 1, 1);
Note
While you technically can use delete for an array, using it would result in getting incorrect results when calling for example Hogwarts.staff.length later on. In other words, delete would remove the element, but it wouldn't update the value of length property. Using delete would also mess up your indexing.
So, when deleting values from an object, always first consider whether you're dealing with object properties or whether you're dealing with array values, and choose the appropriate strategy based on that.
If you want to experiment with this, you can use this Fiddle as a starting point.
I personally use Underscore.js or Lodash for object and array manipulation:
myObject = _.omit(myObject, 'regex');
Using delete method is the best way to do that, as per MDN description, the delete operator removes a property from an object. So you can simply write:
delete myObject.regex;
// OR
delete myObject['regex'];
The delete operator removes a given property from an object. On
successful deletion, it will return true, else false will be returned.
However, it is important to consider the following scenarios:
If the property which you are trying to delete does not exist, delete
will not have any effect and will return true
If a property with the same name exists on the object's prototype
chain, then, after deletion, the object will use the property from the
prototype chain (in other words, delete only has an effect on own
properties).
Any property declared with var cannot be deleted from the global scope
or from a function's scope.
As such, delete cannot delete any functions in the global scope (whether this is part of a function definition or a function (expression).
Functions which are part of an object (apart from the
global scope) can be deleted with delete.
Any property declared with let or const cannot be deleted from the scope within which they were defined. Non-configurable properties cannot be removed. This includes properties of built-in objects like Math, Array, Object and properties that are created as non-configurable with methods like Object.defineProperty().
The following snippet gives another simple example:
var Employee = {
age: 28,
name: 'Alireza',
designation: 'developer'
}
console.log(delete Employee.name); // returns true
console.log(delete Employee.age); // returns true
// When trying to delete a property that does
// not exist, true is returned
console.log(delete Employee.salary); // returns true
For more info about and seeing more examples visit the link below:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete
Another solution, using 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);
However, it will mutate the original object. If you want to create a new object without the specified key, just assign the reduce function to a new variable, e.g.:
(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);
There are a lot of good answers here but I just want to chime in that when using delete to remove a property in JavaScript, it is often wise to first check if that property exists to prevent errors.
E.g
var obj = {"property":"value", "property2":"value"};
if (obj && obj.hasOwnProperty("property2")) {
delete obj.property2;
} else {
//error handling
}
Due to the dynamic nature of JavaScript there are often cases where you simply don't know if the property exists or not. Checking if obj exists before the && also makes sure you don't throw an error due to calling the hasOwnProperty() function on an undefined object.
Sorry if this didn't add to your specific use case but I believe this to be a good design to adapt when managing objects and their properties.
This post is very old and I find it very helpful so I decided to share the unset function I wrote in case someone else see this post and think why it's not so simple as it in PHP unset function.
The reason for writing this new unset function, is to keep the index of all other variables in this hash_map. Look at the following example, and see how the index of "test2" did not change after removing a value from the 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"}
There are a couple of ways to remove properties from an object:
1) Remove using a dot property accessor (mutable)
const myObject = {
"ircEvent": "PRIVMSG",
"method": "newURI",
"regex": "^http://.*",
};
delete myObject.regex;
console.log(myObject);
2. Remove using square brackets property accessor (mutable)
const myObject = {
"ircEvent": "PRIVMSG",
"method": "newURI",
"regex": "^http://.*",
};
delete myObject['regex'];
console.log(myObject);
// or
const name = 'ircEvent';
delete myObject[name];
console.log(myObject);
3) Alternative option but without altering the original object, is using object destructuring and rest syntax (immutable)
const myObject = {
"ircEvent": "PRIVMSG",
"method": "newURI",
"regex": "^http://.*",
};
const { regex, ...myObjectRest} = myObject;
console.log(myObjectRest);
Using ramda#dissoc you will get a new object without the attribute regex:
const newObject = R.dissoc('regex', myObject);
// newObject !== myObject
You can also use other functions to achieve the same effect - omit, pick, ...
Try the following method. Assign the Object property value to undefined. Then stringify the object and parse.
var myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
myObject.regex = undefined;
myObject = JSON.parse(JSON.stringify(myObject));
console.log(myObject);
Using Lodash
import omit from 'lodash/omit';
const prevObject = {test: false, test2: true};
// Removes test2 key from previous object
const nextObject = omit(prevObject, 'test2');
Using Ramda
R.omit(['a', 'd'], {a: 1, b: 2, c: 3, d: 4}); //=> {b: 2, c: 3}
If you want to delete a property deeply nested in the object then you can use the following recursive function with path to the property as the second argument:
var deepObjectRemove = function(obj, path_to_key){
if(path_to_key.length === 1){
delete obj[path_to_key[0]];
return true;
}else{
if(obj[path_to_key[0]])
return deepObjectRemove(obj[path_to_key[0]], path_to_key.slice(1));
else
return false;
}
};
Example:
var a = {
level1:{
level2:{
level3: {
level4: "yolo"
}
}
}
};
deepObjectRemove(a, ["level1", "level2", "level3"]);
console.log(a);
//Prints {level1: {level2: {}}}
Object.assign() & Object.keys() & Array.map()
const obj = {
"Filters":[
{
"FilterType":"between",
"Field":"BasicInformationRow.A0",
"MaxValue":"2017-10-01",
"MinValue":"2017-09-01",
"Value":"Filters value"
}
]
};
let new_obj1 = Object.assign({}, obj.Filters[0]);
let new_obj2 = Object.assign({}, obj.Filters[0]);
/*
// old version
let shaped_obj1 = Object.keys(new_obj1).map(
(key, index) => {
switch (key) {
case "MaxValue":
delete new_obj1["MaxValue"];
break;
case "MinValue":
delete new_obj1["MinValue"];
break;
}
return new_obj1;
}
)[0];
let shaped_obj2 = Object.keys(new_obj2).map(
(key, index) => {
if(key === "Value"){
delete new_obj2["Value"];
}
return new_obj2;
}
)[0];
*/
// new version!
let shaped_obj1 = Object.keys(new_obj1).forEach(
(key, index) => {
switch (key) {
case "MaxValue":
delete new_obj1["MaxValue"];
break;
case "MinValue":
delete new_obj1["MinValue"];
break;
default:
break;
}
}
);
let shaped_obj2 = Object.keys(new_obj2).forEach(
(key, index) => {
if(key === "Value"){
delete new_obj2["Value"];
}
}
);
Dan's assertion that 'delete' is very slow and the benchmark he posted were doubted. So I carried out the test myself in Chrome 59. It does seem that 'delete' is about 30 times slower:
var iterationsTotal = 10000000; // 10 million
var o;
var t1 = Date.now(),t2;
for (let i=0; i<iterationsTotal; i++) {
o = {a:1,b:2,c:3,d:4,e:5};
delete o.a; delete o.b; delete o.c; delete o.d; delete o.e;
}
console.log ((t2=Date.now())-t1); // 6135
for (let i=0; i<iterationsTotal; i++) {
o = {a:1,b:2,c:3,d:4,e:5};
o.a = o.b = o.c = o.d = o.e = undefined;
}
console.log (Date.now()-t2); // 205
Note that I purposely carried out more than one 'delete' operations in one loop cycle to minimize the effect caused by the other operations.
Property Removal in JavaScript
There are many different options presented on this page, not because most of the options are wrong—or because the answers are duplicates—but because the appropriate technique depends on the situation you're in and the goals of the tasks you and/or you team are trying to fulfill. To answer you question unequivocally, one needs to know:
The version of ECMAScript you're targeting
The range of object types you want to remove properties on and the type of property names you need to be able to omit (Strings only? Symbols? Weak references mapped from arbitrary objects? These have all been types of property pointers in JavaScript for years now)
The programming ethos/patterns you and your team use. Do you favor functional approaches and mutation is verboten on your team, or do you employ wild west mutative object-oriented techniques?
Are you looking to achieve this in pure JavaScript or are you willing & able to use a 3rd-party library?
Once those four queries have been answered, there are essentially four categories of "property removal" in JavaScript to chose from in order to meet your goals. They are:
Mutative object property deletion, unsafe
This category is for operating on object literals or object instances when you want to retain/continue to use the original reference and aren't using stateless functional principles in your code. An example piece of syntax in this category:
'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
This category is the oldest, most straightforward & most widely supported category of property removal. It supports Symbol & array indexes in addition to strings and works in every version of JavaScript except for the very first release. However, it's mutative which violates some programming principles and has performance implications. It also can result in uncaught exceptions when used on non-configurable properties in strict mode.
Rest-based string property omission
This category is for operating on plain object or array instances in newer ECMAScript flavors when a non-mutative approach is desired and you don't need to account for Symbol keys:
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 :(
Mutative object property deletion, safe
This category is for operating on object literals or object instances when you want to retain/continue to use the original reference while guarding against exceptions being thrown on unconfigurable properties:
'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
In addition, while mutating objects in-place isn't stateless, you can use the functional nature of Reflect.deleteProperty to do partial application and other functional techniques that aren't possible with delete statements.
Syntax-based string property omission
This category is for operating on plain object or array instances in newer ECMAScript flavors when a non-mutative approach is desired and you don't need to account for Symbol keys:
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 :(
Library-based property omission
This category is generally allows for greater functional flexibility, including accounting for Symbols & omitting more than one property in one statement:
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"
Here's an ES6 way to remove the entry easily:
let myObject = {
"ircEvent": "PRIVMSG",
"method": "newURI",
"regex": "^http://.*"
};
const removeItem = 'regex';
const { [removeItem]: remove, ...rest } = myObject;
console.log(remove); // "^http://.*"
console.log(rest); // Object { ircEvent: "PRIVMSG", method: "newURI" }
#johnstock, we can also use JavaScript's prototyping concept to add method to objects to delete any passed key available in calling object.
Above answers are appreciated.
var myObject = {
"ircEvent": "PRIVMSG",
"method": "newURI",
"regex": "^http://.*"
};
// 1st and direct way
delete myObject.regex; // delete myObject["regex"]
console.log(myObject); // { ircEvent: 'PRIVMSG', method: 'newURI' }
// 2 way - by using the concept of JavaScript's prototyping concept
Object.prototype.removeFromObjectByKey = function(key) {
// If key exists, remove it and return true
if (this[key] !== undefined) {
delete this[key]
return true;
}
// Else return false
return false;
}
var isRemoved = myObject.removeFromObjectByKey('method')
console.log(myObject) // { ircEvent: 'PRIVMSG' }
// More examples
var obj = {
a: 45,
b: 56,
c: 67
}
console.log(obj) // { a: 45, b: 56, c: 67 }
// Remove key 'a' from obj
isRemoved = obj.removeFromObjectByKey('a')
console.log(isRemoved); //true
console.log(obj); // { b: 56, c: 67 }
// Remove key 'd' from obj which doesn't exist
var isRemoved = obj.removeFromObjectByKey('d')
console.log(isRemoved); // false
console.log(obj); // { b: 56, c: 67 }
You can use a filter like below
var myObject = {
"ircEvent": "PRIVMSG",
"method": "newURI",
"regex": "^http://.*"
};
// Way 1
let filter1 = {}
Object.keys({...myObject}).filter(d => {
if(d !== 'regex'){
filter1[d] = myObject[d];
}
})
console.log(filter1)
// Way 2
let filter2 = Object.fromEntries(Object.entries({...myObject}).filter(d =>
d[0] !== 'regex'
))
console.log(filter2)
I have used Lodash "unset" to make it happen for a nested object also... only this needs to write small logic to get the path of the property key which is expected by the omit method.
Method which returns the property path as an array
var a = {"bool":{"must":[{"range":{"price_index.final_price":{"gt":"450", "lt":"500"}}}, {"bool":{"should":[{"term":{"color_value.keyword":"Black"}}]}}]}};
function getPathOfKey(object,key,currentPath, t){
var currentPath = currentPath || [];
for(var i in object){
if(i == key){
t = currentPath;
}
else if(typeof object[i] == "object"){
currentPath.push(i)
return getPathOfKey(object[i], key,currentPath)
}
}
t.push(key);
return t;
}
document.getElementById("output").innerHTML =JSON.stringify(getPathOfKey(a,"price_index.final_price"))
<div id="output">
</div>
Then just using Lodash unset method remove property from object.
var unset = require('lodash.unset');
unset(a, getPathOfKey(a, "price_index.final_price"));
let myObject = {
"ircEvent": "PRIVMSG",
"method": "newURI",
"regex": "^http://.*"
};
obj = Object.fromEntries(
Object.entries(myObject).filter(function (m){
return m[0] != "regex"/*or whatever key to delete*/
}
))
console.log(obj)
You can also just treat the object like a2d array using Object.entries, and use splice to remove an element as you would in a normal array, or simply filter through the object, as one would an array, and assign the reconstructed object back to the original variable
If you don't want to modify the original object.
Remove a property without mutating the object
If mutability is a concern, you can create a completely new object by copying all the properties from the old, except the one you want to remove.
let myObject = {
"ircEvent": "PRIVMSG",
"method": "newURI",
"regex": "^http://.*"
};
let prop = 'regex';
const updatedObject = Object.keys(myObject).reduce((object, key) => {
if (key !== prop) {
object[key] = myObject[key]
}
return object
}, {})
console.log(updatedObject);

Categories

Resources