Description
Unlike what common belief suggests (perhaps due to other programming languages like
delete in C++),
the delete
operator has nothing to do with directly freeing memory.
Memory management is done indirectly via breaking references.
See the memory management page for more details.
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 returntrue
. -
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
.
-
As such,
-
Any property declared with
let
orconst
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 likeObject.defineProperty()
.
The following snippet gives a simple example:
const Employee = { age: 28, name: 'abc', 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
Non-configurable properties
When a property is marked as non-configurable, delete
won't have any
effect, and will return false
. In strict mode this will raise a
TypeError
.
const Employee = {}; Object.defineProperty(Employee, 'name', { configurable: false }); console.log(delete Employee.name); // returns false
var
, let
, and
const
create non-configurable properties that cannot
be deleted with the delete
operator:
var nameOther = 'XYZ'; // We can access this global property using: Object.getOwnPropertyDescriptor(window, 'nameOther'); // output: Object {value: "XYZ", // writable: true, // enumerable: true, // configurable: false} // Since "nameOther" is added using with the // var keyword, it is marked as "non-configurable" delete nameOther; // return false
In strict mode, this would have raised an exception.
Strict vs. non-strict mode
When in strict mode, if delete
is used on a direct reference to a
variable, a function argument or a function name, it will throw a
SyntaxError
. Therefore, to avoid syntax errors in
strict mode, you must use the delete
operator in the form of
delete object.property
or delete object['property']
.
Object.defineProperty(globalThis, 'variable1', { value: 10, configurable: true, }); Object.defineProperty(globalThis, 'variable2', { value: 10, configurable: false, }); // SyntaxError in strict mode. console.log(delete variable1); // true // SyntaxError in strict mode. console.log(delete variable2); // false
function func(param) { // SyntaxError in strict mode. console.log(delete param); // false } // SyntaxError in strict mode. console.log(delete func); // false
Cross-browser notes
As of modern ECMAScript specification, the traversal order of object
properties is well-defined and stable across implementations. However,
in the
case of Internet Explorer, when one uses delete
on a property, some
confusing behavior results, preventing other browsers from using simple objects like
object literals as ordered associative arrays. In Explorer, while the property
value is indeed set to undefined
, if one later adds back a
property with the same name, the property will be iterated in its old
position--not at the end of the iteration sequence as one might expect after having
deleted the property and then added it back.
If you want to use an ordered associative array with support of old runtimes, use a Map
object if available (through a polyfill, for example), or simulate this
structure with two separate arrays (one for the keys and the other for
the values), or build an array of single-property objects, etc.