Say I create an object as follows:
let myObject = {
"ircEvent": "PRIVMSG",
"method": "newURI",
"regex": "^http://.*"
};
What is the best way to remove the property regex
to end up with new myObject
as follows?
let myObject = {
"ircEvent": "PRIVMSG",
"method": "newURI"
};
This question is related to
javascript
javascript-objects
Two ways to delete an object
using for in
function deleteUser(key) {
const newUsers = {};
for (const uid in users) {
if (uid !== key) {
newUsers[uid] = users[uid];
}
return newUsers
}
or
delete users[key]
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);
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}
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.
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, ...
@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 }
_x000D_
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"}
_x000D_
To clone object without property:
For example:
let object = { a: 1, b: 2, c: 3 };
And we need to delete a
.
const { a, ...rest } = object;
object = rest;
const propKey = 'a';
const { [propKey]: propValue, ...rest } = object;
object = rest;
const removeProperty = (propKey, { [propKey]: propValue, ...rest }) => rest;
object = removeProperty('a', object);
const removeProperties = (object, ...keys) => Object.entries(object).reduce((prev, [key, value]) => ({...prev, ...(!keys.includes(key) && { [key]: value }) }), {})
Usage
object = removeProperties(object, 'a', 'b') // result => { c: 3 }
Or
const propsToRemove = ['a', 'b']
object = removeProperties(object, ...propsToRemove) // result => { c: 3 }
const obj = {_x000D_
"Filters":[_x000D_
{_x000D_
"FilterType":"between",_x000D_
"Field":"BasicInformationRow.A0",_x000D_
"MaxValue":"2017-10-01",_x000D_
"MinValue":"2017-09-01",_x000D_
"Value":"Filters value"_x000D_
}_x000D_
]_x000D_
};_x000D_
_x000D_
let new_obj1 = Object.assign({}, obj.Filters[0]);_x000D_
let new_obj2 = Object.assign({}, obj.Filters[0]);_x000D_
_x000D_
/*_x000D_
_x000D_
// old version_x000D_
_x000D_
let shaped_obj1 = Object.keys(new_obj1).map(_x000D_
(key, index) => {_x000D_
switch (key) {_x000D_
case "MaxValue":_x000D_
delete new_obj1["MaxValue"];_x000D_
break;_x000D_
case "MinValue":_x000D_
delete new_obj1["MinValue"];_x000D_
break;_x000D_
}_x000D_
return new_obj1;_x000D_
}_x000D_
)[0];_x000D_
_x000D_
_x000D_
let shaped_obj2 = Object.keys(new_obj2).map(_x000D_
(key, index) => {_x000D_
if(key === "Value"){_x000D_
delete new_obj2["Value"];_x000D_
}_x000D_
return new_obj2;_x000D_
}_x000D_
)[0];_x000D_
_x000D_
_x000D_
*/_x000D_
_x000D_
_x000D_
// new version!_x000D_
_x000D_
let shaped_obj1 = Object.keys(new_obj1).forEach(_x000D_
(key, index) => {_x000D_
switch (key) {_x000D_
case "MaxValue":_x000D_
delete new_obj1["MaxValue"];_x000D_
break;_x000D_
case "MinValue":_x000D_
delete new_obj1["MinValue"];_x000D_
break;_x000D_
default:_x000D_
break;_x000D_
}_x000D_
}_x000D_
);_x000D_
_x000D_
let shaped_obj2 = Object.keys(new_obj2).forEach(_x000D_
(key, index) => {_x000D_
if(key === "Value"){_x000D_
delete new_obj2["Value"];_x000D_
}_x000D_
}_x000D_
);
_x000D_
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 purposedly carried out more than one 'delete' operations in one loop cycle to minimize the effect caused by the other operations.
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 gets 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 info on Object.seal
: Object.seal()
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://.*"};_x000D_
_x000D_
myObject.regex = undefined;_x000D_
myObject = JSON.parse(JSON.stringify(myObject));_x000D_
_x000D_
console.log(myObject);
_x000D_
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:
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:
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.
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 :(
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.
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 :(
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"
Another solution, using Array#reduce
.
var myObject = {_x000D_
"ircEvent": "PRIVMSG",_x000D_
"method": "newURI",_x000D_
"regex": "^http://.*"_x000D_
};_x000D_
_x000D_
myObject = Object.keys(myObject).reduce(function(obj, key) {_x000D_
if (key != "regex") { //key you want to remove_x000D_
obj[key] = myObject[key];_x000D_
}_x000D_
return obj;_x000D_
}, {});_x000D_
_x000D_
console.log(myObject);
_x000D_
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 = {_x000D_
ircEvent: 'PRIVMSG',_x000D_
method: 'newURI',_x000D_
regex: '^http://.*',_x000D_
};_x000D_
_x000D_
const myNewObject = Object.keys(myObject).reduce((obj, key) => {_x000D_
key !== 'regex' ? obj[key] = myObject[key] : null;_x000D_
return obj;_x000D_
}, {});_x000D_
_x000D_
console.log(myNewObject);
_x000D_
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',
...
]
};
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'];
.
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);
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');
You can use 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)
_x000D_
To whoever needs it...
To complete @Koen answer in this thread, in case you want to remove dynamic variable using the spread syntax, you can do it like so:
const key = 'a';_x000D_
_x000D_
const { [key]: foo, ...rest } = { a: 1, b: 2, c: 3 };_x000D_
_x000D_
console.log(foo); // 1_x000D_
console.log(rest); // { b: 2, c: 3 }
_x000D_
* foo
will be a new variable with the value of a
(which is 1).
EXTENDED ANSWER
There are few common ways to remove a property from an object.
Each one has it's own pros and cons (check this performance comparison):
Delete Operator
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
More than 2X 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 not suggested to be used when you need to remove many properties at a time.
{ [key]: val, ...rest } = obj;
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"}
_x000D_
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)
_x000D_
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
var myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};_x000D_
_x000D_
delete myObject.regex;_x000D_
_x000D_
console.log ( myObject.regex); // logs: undefined
_x000D_
This works in Firefox and Internet Explorer, and I think it works in all others.
The obvious way to remove a property from an object is to use the delete keyword. this can be done like this:
delete myObject['regex']
or this:
delete myObject.regex
If you are cocerned with mutability, you can create a new object by copying all the properties from the old, except the one you would like to remove
let myObject = {
ircEvent: "PRIVMSG",
method: "newURI",
regex: "^http://.*"
};
const propertyToRemove = 'regex'
const newObject = Object.keys(myObject).reduce((object, key) => {
if (key !== propertyToRemove ) {
object[key] = car[key]
}
return object }, {})
var myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};_x000D_
_x000D_
delete myObject.regex;_x000D_
_x000D_
console.log ( myObject.regex); // logs: undefined
_x000D_
This works in Firefox and Internet Explorer, and I think it works in all others.
I have used lodash "unset" to make it happen for nested object also.. only this need to write small logic to get path of property key which expected by omit method.
var a = {"bool":{"must":[{"range":{"price_index.final_price":{"gt":"450","lt":"500"}}},{"bool":{"should":[{"term":{"color_value.keyword":"Black"}}]}}]}};_x000D_
_x000D_
function getPathOfKey(object,key,currentPath, t){_x000D_
var currentPath = currentPath || [];_x000D_
_x000D_
for(var i in object){_x000D_
if(i == key){_x000D_
t = currentPath;_x000D_
}_x000D_
else if(typeof object[i] == "object"){_x000D_
currentPath.push(i)_x000D_
return getPathOfKey(object[i], key,currentPath)_x000D_
}_x000D_
}_x000D_
t.push(key);_x000D_
return t;_x000D_
}_x000D_
document.getElementById("output").innerHTML =JSON.stringify(getPathOfKey(a,"price_index.final_price"))
_x000D_
<div id="output"> _x000D_
_x000D_
</div>
_x000D_
var unset = require('lodash.unset');_x000D_
unset(a,getPathOfKey(a,"price_index.final_price"));
_x000D_
var myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};_x000D_
_x000D_
delete myObject.regex;_x000D_
_x000D_
console.log ( myObject.regex); // logs: undefined
_x000D_
This works in Firefox and Internet Explorer, and I think it works in all others.
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: {}}}
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.
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:
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:
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.
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 :(
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.
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 :(
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"
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 from 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 = {_x000D_
age: 28,_x000D_
name: 'Alireza',_x000D_
designation: 'developer'_x000D_
}_x000D_
_x000D_
console.log(delete Employee.name); // returns true_x000D_
console.log(delete Employee.age); // returns true_x000D_
_x000D_
// When trying to delete a property that does _x000D_
// not exist, true is returned _x000D_
console.log(delete Employee.salary); // returns true
_x000D_
For more info about and seeing more example, visit the link below:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete
The obvious way to remove a property from an object is to use the delete keyword. this can be done like this:
delete myObject['regex']
or this:
delete myObject.regex
If you are cocerned with mutability, you can create a new object by copying all the properties from the old, except the one you would like to remove
let myObject = {
ircEvent: "PRIVMSG",
method: "newURI",
regex: "^http://.*"
};
const propertyToRemove = 'regex'
const newObject = Object.keys(myObject).reduce((object, key) => {
if (key !== propertyToRemove ) {
object[key] = car[key]
}
return object }, {})
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 = {_x000D_
myProperty: 1 _x000D_
}_x000D_
console.log(obj.hasOwnProperty('myProperty')) // true_x000D_
delete obj.myProperty_x000D_
console.log(obj.hasOwnProperty('myProperty')) // false
_x000D_
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.
I personally use Underscore.js or Lodash for object and array manipulation:
myObject = _.omit(myObject, 'regex');
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 gets 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 info 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
To clone object without property:
For example:
let object = { a: 1, b: 2, c: 3 };
And we need to delete a
.
const { a, ...rest } = object;
object = rest;
const propKey = 'a';
const { [propKey]: propValue, ...rest } = object;
object = rest;
const removeProperty = (propKey, { [propKey]: propValue, ...rest }) => rest;
object = removeProperty('a', object);
const removeProperties = (object, ...keys) => Object.entries(object).reduce((prev, [key, value]) => ({...prev, ...(!keys.includes(key) && { [key]: value }) }), {})
Usage
object = removeProperties(object, 'a', 'b') // result => { c: 3 }
Or
const propsToRemove = ['a', 'b']
object = removeProperties(object, ...propsToRemove) // result => { c: 3 }
const obj = {_x000D_
"Filters":[_x000D_
{_x000D_
"FilterType":"between",_x000D_
"Field":"BasicInformationRow.A0",_x000D_
"MaxValue":"2017-10-01",_x000D_
"MinValue":"2017-09-01",_x000D_
"Value":"Filters value"_x000D_
}_x000D_
]_x000D_
};_x000D_
_x000D_
let new_obj1 = Object.assign({}, obj.Filters[0]);_x000D_
let new_obj2 = Object.assign({}, obj.Filters[0]);_x000D_
_x000D_
/*_x000D_
_x000D_
// old version_x000D_
_x000D_
let shaped_obj1 = Object.keys(new_obj1).map(_x000D_
(key, index) => {_x000D_
switch (key) {_x000D_
case "MaxValue":_x000D_
delete new_obj1["MaxValue"];_x000D_
break;_x000D_
case "MinValue":_x000D_
delete new_obj1["MinValue"];_x000D_
break;_x000D_
}_x000D_
return new_obj1;_x000D_
}_x000D_
)[0];_x000D_
_x000D_
_x000D_
let shaped_obj2 = Object.keys(new_obj2).map(_x000D_
(key, index) => {_x000D_
if(key === "Value"){_x000D_
delete new_obj2["Value"];_x000D_
}_x000D_
return new_obj2;_x000D_
}_x000D_
)[0];_x000D_
_x000D_
_x000D_
*/_x000D_
_x000D_
_x000D_
// new version!_x000D_
_x000D_
let shaped_obj1 = Object.keys(new_obj1).forEach(_x000D_
(key, index) => {_x000D_
switch (key) {_x000D_
case "MaxValue":_x000D_
delete new_obj1["MaxValue"];_x000D_
break;_x000D_
case "MinValue":_x000D_
delete new_obj1["MinValue"];_x000D_
break;_x000D_
default:_x000D_
break;_x000D_
}_x000D_
}_x000D_
);_x000D_
_x000D_
let shaped_obj2 = Object.keys(new_obj2).forEach(_x000D_
(key, index) => {_x000D_
if(key === "Value"){_x000D_
delete new_obj2["Value"];_x000D_
}_x000D_
}_x000D_
);
_x000D_
@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 }
_x000D_
Two ways to delete an object
using for in
function deleteUser(key) {
const newUsers = {};
for (const uid in users) {
if (uid !== key) {
newUsers[uid] = users[uid];
}
return newUsers
}
or
delete users[key]
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);
_x000D_
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 purposedly carried out more than one 'delete' operations in one loop cycle to minimize the effect caused by the other operations.
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 from 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 = {_x000D_
age: 28,_x000D_
name: 'Alireza',_x000D_
designation: 'developer'_x000D_
}_x000D_
_x000D_
console.log(delete Employee.name); // returns true_x000D_
console.log(delete Employee.age); // returns true_x000D_
_x000D_
// When trying to delete a property that does _x000D_
// not exist, true is returned _x000D_
console.log(delete Employee.salary); // returns true
_x000D_
For more info about and seeing more example, visit the link below:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete
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]
delete
in JavaScript has a different function to that of the keyword in C and C++: it does not directly free memory. Instead, its sole purpose is to remove properties from objects.
For arrays, deleting a property corresponding to an index, creates a sparse array (ie. an array with a "hole" in it). Most browsers represent these missing array indices as "empty".
var array = [0, 1, 2, 3]
delete array[2] // [0, 1, empty, 3]
Note that delete
does not relocate array[3]
into array[2]
.
Different built-in functions in JavaScript handle sparse arrays differently.
for...in
will skip the empty index completely.
A traditional for
loop will return 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.
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
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
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
removes the last element from an array, and returns that element. This operation changes the length of the array.
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.
You can use 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)
_x000D_
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://.*"};_x000D_
_x000D_
myObject.regex = undefined;_x000D_
myObject = JSON.parse(JSON.stringify(myObject));_x000D_
_x000D_
console.log(myObject);
_x000D_
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}
I have used lodash "unset" to make it happen for nested object also.. only this need to write small logic to get path of property key which expected by omit method.
var a = {"bool":{"must":[{"range":{"price_index.final_price":{"gt":"450","lt":"500"}}},{"bool":{"should":[{"term":{"color_value.keyword":"Black"}}]}}]}};_x000D_
_x000D_
function getPathOfKey(object,key,currentPath, t){_x000D_
var currentPath = currentPath || [];_x000D_
_x000D_
for(var i in object){_x000D_
if(i == key){_x000D_
t = currentPath;_x000D_
}_x000D_
else if(typeof object[i] == "object"){_x000D_
currentPath.push(i)_x000D_
return getPathOfKey(object[i], key,currentPath)_x000D_
}_x000D_
}_x000D_
t.push(key);_x000D_
return t;_x000D_
}_x000D_
document.getElementById("output").innerHTML =JSON.stringify(getPathOfKey(a,"price_index.final_price"))
_x000D_
<div id="output"> _x000D_
_x000D_
</div>
_x000D_
var unset = require('lodash.unset');_x000D_
unset(a,getPathOfKey(a,"price_index.final_price"));
_x000D_
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, ...
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.
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
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://.*"};_x000D_
_x000D_
delete myObject.regex;_x000D_
_x000D_
console.log ( myObject.regex); // logs: undefined
_x000D_
This works in Firefox and Internet Explorer, and I think it works in all others.
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" }
_x000D_
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);
_x000D_
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: {}}}
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]
delete
in JavaScript has a different function to that of the keyword in C and C++: it does not directly free memory. Instead, its sole purpose is to remove properties from objects.
For arrays, deleting a property corresponding to an index, creates a sparse array (ie. an array with a "hole" in it). Most browsers represent these missing array indices as "empty".
var array = [0, 1, 2, 3]
delete array[2] // [0, 1, empty, 3]
Note that delete
does not relocate array[3]
into array[2]
.
Different built-in functions in JavaScript handle sparse arrays differently.
for...in
will skip the empty index completely.
A traditional for
loop will return 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.
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
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
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
removes the last element from an array, and returns that element. This operation changes the length of the array.
Another solution, using Array#reduce
.
var myObject = {_x000D_
"ircEvent": "PRIVMSG",_x000D_
"method": "newURI",_x000D_
"regex": "^http://.*"_x000D_
};_x000D_
_x000D_
myObject = Object.keys(myObject).reduce(function(obj, key) {_x000D_
if (key != "regex") { //key you want to remove_x000D_
obj[key] = myObject[key];_x000D_
}_x000D_
return obj;_x000D_
}, {});_x000D_
_x000D_
console.log(myObject);
_x000D_
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 = {_x000D_
ircEvent: 'PRIVMSG',_x000D_
method: 'newURI',_x000D_
regex: '^http://.*',_x000D_
};_x000D_
_x000D_
const myNewObject = Object.keys(myObject).reduce((obj, key) => {_x000D_
key !== 'regex' ? obj[key] = myObject[key] : null;_x000D_
return obj;_x000D_
}, {});_x000D_
_x000D_
console.log(myNewObject);
_x000D_
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" }
_x000D_
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 = {_x000D_
myProperty: 1 _x000D_
}_x000D_
console.log(obj.hasOwnProperty('myProperty')) // true_x000D_
delete obj.myProperty_x000D_
console.log(obj.hasOwnProperty('myProperty')) // false
_x000D_
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.
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)
_x000D_
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
To whoever needs it...
To complete @Koen answer in this thread, in case you want to remove dynamic variable using the spread syntax, you can do it like so:
const key = 'a';_x000D_
_x000D_
const { [key]: foo, ...rest } = { a: 1, b: 2, c: 3 };_x000D_
_x000D_
console.log(foo); // 1_x000D_
console.log(rest); // { b: 2, c: 3 }
_x000D_
* foo
will be a new variable with the value of a
(which is 1).
EXTENDED ANSWER
There are few common ways to remove a property from an object.
Each one has it's own pros and cons (check this performance comparison):
Delete Operator
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
More than 2X 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 not suggested to be used when you need to remove many properties at a time.
{ [key]: val, ...rest } = obj;
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',
...
]
};
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'];
.
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);
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.
Source: Stackoverflow.com