Please note, this is a STATIC archive of website developer.mozilla.org from 03 Nov 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

Revision 1126285 of delete operator

  • Revision slug: Web/JavaScript/Reference/Operators/delete
  • Revision title: delete operator
  • Revision id: 1126285
  • Created:
  • Creator: DrNio13
  • Is current revision? No
  • Comment

Revision Content

{{jsSidebar("Operators")}}

The delete operator removes a property from an object.

Syntax

delete expression 

where expression should evaluate to a property reference, e.g.:

delete object.property
delete object['property']

Parameters

object
The name of an object, or an expression evaluating to an object.
property
The property to delete.

Return value

true for all cases except when the property is an own non-configurable property, in which case, false is returned in non-strict mode.

Exceptions

Throws {{jsxref("Global_objects/SyntaxError")}} in strict mode if the property is an own non-configurable property.

Description

Unlike what common belief suggests, the delete operator has nothing to do with directly freeing memory. Memory managment 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 succesful 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 exists, 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 protoype chain (in other words, delete only has an effect on own properties).
  • Any property declared with {{jsxref("Statements/var","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.
  • Non-configurable properties cannot be removed. This includes properties of built-in objects like {{jsxref("Math")}}, {{jsxref("Array")}}, {{jsxref("Object")}} and properties that are created as non-configurable with methods like {{jsxref("Object.defineProperty()")}}.

The following snippet gives a simple example:

var 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 exists, 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 SyntaxError.

var Employee = {};
Object.defineProperty(Employee, 'name', {configurable: false})

console.log(delete Employee.name);  // returns false

{{jsxref("Statements/var","var")}} creates non-configurable properties that cannot be deleted with the delete operator:

var name = 'XYZ';

// We can access this global property using:
Object.getOwnPropertyDescriptor(window, 'name')   

// output: Object {value: "", 
                  writable: true, 
                  enumerable: true,
                  configurable: false}

// Since "name" is added using with the
// var keyword, it is marked as "non-configurable"

delete name;   // return false

In strict mode, this would have risen 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 {{jsxref("SyntaxError")}}.

Any variable defined with var is marked as non-configurable. In the following example, salary is non-configurable and cannot be deleted. In non-strict mode, the delete operation will return false.

function Employee() { 
  delete salary;
  var salary;
}

Employee()

Let's see how the same code behaves in strict mode. Instead of returning false, the statement raises a SyntaxError.

"use strict";

function Employee() {
  delete salary;  // SyntaxError
  var salary;        
}

// Similarly, any direct access to a function
// with delete will raise a SyntaxError

function DemoFunction() {
  //some code
}

delete DemoFunction; // SyntaxError

Examples

// creates the property adminName on the global scope
adminName = 'xyz';            

// creates the property empCount on the global scope
// Since we are using var, this is marked as non-configurable
var empCount = 43;

EmployeeDetails = {
  name: 'xyz',
  age: 5,
  designation: 'Developer'
};

// adminName is a property of the global scope.
// It can be deleted since it is created without var.
// Therefore, it is configurable.
delete adminName;       // returns true

// On the contrary, empCount is not configurable, 
// since var was used.
delete empCount;       // returns false 

// delete can be used to remove properties from objects  
delete EmployeeDetails.name; // returns true 

// Even when the property does not exists, it returns "true"
delete EmployeeDetails.salary; // returns true 

// delete does not affect built-in static properties
delete Math.PI; // returns false 

// EmployeeDetails is a property of the global scope.
// Since it defined without "var", it is marked configurable
delete EmployeeDetails;   // returns true

function f() {
  var z = 44;

  // delete doesn't affect local variable names
  delete z;     // returns false
}

delete and the prototype chain

In the following example, we delete an own property of an object while a property with the same name is available on the prototype chain:

function Foo(){
  this.bar = 10;
}

Foo.prototype.bar = 42;

var foo = new Foo();

// Returns true, since the own property
// has been deleted on the foo object
delete foo.bar;           

// foo.bar is still available, since it 
// is available in the prototype chain.
console.log(foo.bar);

// We delete the property on the prototype
delete Foo.prototype.bar; 

// logs "undefined" since the property
// is no longer inherited
console.log(foo.bar);           

Deleting array elements

When you delete an array element, the array length is not affected. This holds even if you delete the last element of the array.

When the delete operator removes an array element, that element is no longer in the array. In the following example, trees[3] is removed with delete.

var trees = ["redwood","bay","cedar","oak","maple"];
delete trees[3];
if (3 in trees) {
    // this does not get executed
}

If you want an array element to exist but have an undefined value, use the undefined value instead of the delete operator. In the following example, trees[3] is assigned the value undefined, but the array element still exists:

var trees = ["redwood","bay","cedar","oak","maple"];
trees[3] = undefined;
if (3 in trees) {
    // this gets executed
}

Specifications

Specification Status Comment
{{SpecName('ESDraft', '#sec-delete-operator', 'The delete Operator')}} {{Spec2('ESDraft')}}  
{{SpecName('ES6', '#sec-delete-operator', 'The delete Operator')}} {{Spec2('ES6')}}  
{{SpecName('ES5.1', '#sec-11.4.1', 'The delete Operator')}} {{Spec2('ES5.1')}}  
{{SpecName('ES1', '#sec-11.4.1', 'The delete Operator')}} {{Spec2('ES1')}} Initial definition. Implemented in JavaScript 1.2.

Browser compatibility

{{CompatibilityTable}}

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support {{CompatVersionUnknown}} {{CompatVersionUnknown}} {{CompatVersionUnknown}} {{CompatVersionUnknown}} {{CompatVersionUnknown}}
Temporal dead zone {{CompatUnknown}} {{CompatGeckoDesktop(36)}} {{CompatUnknown}} {{CompatUnknown}} {{CompatUnknown}}
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support {{CompatVersionUnknown}} {{CompatVersionUnknown}} {{CompatVersionUnknown}} {{CompatVersionUnknown}} {{CompatVersionUnknown}} {{CompatVersionUnknown}}
Temporal dead zone {{CompatUnknown}} {{CompatUnknown}} {{CompatGeckoMobile(36)}} {{CompatUnknown}} {{CompatUnknown}} {{CompatUnknown}}

Cross-browser notes

Although ECMAScript makes iteration order of objects implementation-dependent, it may appear that all major browsers support an iteration order based on the earliest added property coming first (at least for properties not on the prototype). 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.

So, if you want to simulate an ordered associative array in a cross-browser environment, you are forced to either use two separate arrays (one for the keys and the other for the values), or build an array of single-property objects, etc.

See also

Revision Source

<div>{{jsSidebar("Operators")}}</div>

<p>The <strong><code>delete</code> operator</strong> removes a property from an object.</p>

<h2 id="Syntax">Syntax</h2>

<pre class="syntaxbox">
delete <em>expression</em> </pre>

<p>where <em>expression</em> should evaluate to a property reference, e.g.:</p>

<pre class="syntaxbox">
delete <em>object.property</em>
delete <em>object</em>['<em>property</em>']
</pre>

<h3 id="Parameters">Parameters</h3>

<dl>
 <dt><code>object</code></dt>
 <dd>The name of an object, or an expression evaluating to an object.</dd>
 <dt><code>property</code></dt>
 <dd>The property to delete.</dd>
</dl>

<h3 id="Return_value">Return value</h3>

<p><code>true</code> for all cases except when the property is an own non-configurable property, in which case, <code>false</code> is returned in non-strict mode.</p>

<h3 id="Exceptions">Exceptions</h3>

<p>Throws {{jsxref("Global_objects/SyntaxError")}} in <a href="/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode">strict mode</a> if the property is an own non-configurable property.</p>

<h2 id="Description">Description</h2>

<p>Unlike what common belief suggests, the <code>delete</code> operator has <strong>nothing</strong> to do with directly freeing memory. Memory managment is done indirectly via breaking references, see the <a href="/en-US/docs/Web/JavaScript/Memory_Management">memory management</a> page for more details.</p>

<p>The <code><strong>delete</strong></code> operator removes a given property from an object. On succesful deletion, it will return <code>true,</code> else <code>false</code> will be&nbsp;returned. However, it is important to consider the following scenarios:</p>

<ul>
 <li>If the property which you are trying to delete does not exists, <code>delete</code> will not have any effect and will return <code>true</code></li>
 <li>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 protoype chain (in other words, <code>delete</code> only has an effect on own properties).</li>
 <li>Any property declared with {{jsxref("Statements/var","var")}} cannot be deleted from the global scope or from a function's scope.
  <ul>
   <li>As such, <code>delete</code> cannot delete any functions in the global scope (whether this is part from a function definition or a function expression).</li>
   <li>Functions which are part of an object (apart from the global scope) can&nbsp;be deleted with <code>delete</code>.</li>
  </ul>
 </li>
 <li>Non-configurable properties cannot be removed. This includes properties of built-in objects like {{jsxref("Math")}}, {{jsxref("Array")}}, {{jsxref("Object")}} and properties that are created as non-configurable with methods like {{jsxref("Object.defineProperty()")}}.</li>
</ul>

<p>The following snippet gives a simple example:</p>

<pre class="brush: js">
var Employee = {
&nbsp; 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 exists, true is returned 
console.log(delete Employee.salary) // returns true
</pre>

<h3 id="Non-configurable_properties"><strong>Non-configurable properties</strong></h3>

<p>When a property is marked as non-configurable, <code>delete</code> won't have any effect, and will return <code>false</code>. In strict mode&nbsp;this will raise a <code>SyntaxError</code>.</p>

<pre class="brush: js">
var Employee = {};
Object.defineProperty(Employee, 'name', {configurable: false})

console.log(delete Employee.name);  // returns false
</pre>

<p>{{jsxref("Statements/var","var")}} creates non-configurable properties that cannot be deleted with the <code>delete</code> operator:</p>

<pre class="brush: js">
var name = 'XYZ';

// We can access this global property using:
Object.getOwnPropertyDescriptor(window, 'name')   

// output: Object {value: "", 
                  writable: true, 
                  enumerable: true,
                  <strong>configurable: false</strong>}

// Since "name" is added using with the
// var keyword, it is marked as "non-configurable"

delete name;   // return false</pre>

<p>In strict mode, this would have risen an exception.</p>

<h3 id="Strict_vs._non-strict_mode"><strong>Strict vs. non-strict mode</strong></h3>

<p>When in strict mode, if <code>delete</code> is used on a direct reference to a variable, a function argument or a function name, it will throw a {{jsxref("SyntaxError")}}<strong>.</strong></p>

<p>Any variable defined with <code>var</code> is marked as non-configurable. In the following example, <code>salary</code> is non-configurable and cannot be deleted. In non-strict mode, the <code>delete</code> operation will return <code>false</code>.</p>

<pre class="brush: js">
function Employee() { 
  delete salary;
  var salary;
}

Employee()
</pre>

<p>Let's see how the same code behaves in strict mode. Instead of returning <code>false</code>, the statement raises a <code>SyntaxError</code>.</p>

<pre class="brush: js">
"use strict";

function Employee() {
&nbsp; delete salary;  // SyntaxError
&nbsp; var salary;        
}

// Similarly, any direct access to a function
// with delete will raise a SyntaxError

function DemoFunction() {
  //some code
}

delete DemoFunction; // SyntaxError
</pre>

<h2 id="Examples">Examples</h2>

<pre class="brush: js">
// creates the property adminName on the global scope
adminName = 'xyz';            

// creates the property empCount on the global scope
// Since we are using var, this is marked as non-configurable
var empCount = 43;

EmployeeDetails = {
  name: 'xyz',
  age: 5,
&nbsp; designation: 'Developer'
};

// adminName is a property of the global scope.
// It can be deleted since it is created without var.
// Therefore, it is configurable.
delete adminName;       // returns true

// On the contrary, empCount is not configurable, 
// since var was used.
delete empCount;       // returns false 

// delete can be used to remove properties from objects  
delete EmployeeDetails.name; // returns true 

<strong>// </strong>Even when the property does not exists, it returns "true"
delete EmployeeDetails.salary; // returns true 

// delete does not affect built-in static properties
delete Math.PI; // returns false 

// EmployeeDetails is a property of the global scope.
// Since it defined without "var", it is marked configurable
delete EmployeeDetails;   // returns true

function f() {
  var z = 44;

  // delete doesn't affect local variable names
  delete z;     // returns false
}
</pre>

<h3 id="delete_and_the_prototype_chain"><code>delete</code> and the prototype chain</h3>

<p>In the following example, we delete an own property of an object while a property with the same name is available on the prototype chain:</p>

<pre class="brush: js">
function Foo(){
  this.bar = 10;
}

Foo.prototype.bar = 42;

var foo = new Foo();

// Returns true, since the own property
// has been deleted on the foo object
delete foo.bar;           

// foo.bar is still available, since it 
// is available in the prototype chain.
console.log(foo.bar);

// We delete the property on the prototype
delete Foo.prototype.bar; 

// logs "undefined" since the property
// is no longer inherited
console.log(foo.bar);           </pre>

<h3 id="Deleting_array_elements"><strong>Deleting array elements</strong></h3>

<p>When you delete an array element, the array length is not affected. This holds even if you delete the last element of the array.</p>

<p>When the <code>delete</code> operator removes an array element, that element is no longer in the array. In the following example, <code>trees[3]</code> is removed with <code>delete</code>.</p>

<pre class="brush: js">
var trees = ["redwood","bay","cedar","oak","maple"];
delete trees[3];
if (3 in trees) {
    // this does not get executed
}</pre>

<p>If you want an array element to exist but have an undefined value, use the <code>undefined</code> value instead of the <code>delete</code> operator. In the following example, <code>trees[3]</code> is assigned the value undefined, but the array element still exists:</p>

<pre class="brush: js">
var trees = ["redwood","bay","cedar","oak","maple"];
trees[3] = undefined;
if (3 in trees) {
    // this gets executed
}</pre>

<h2 id="Specifications">Specifications</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">Specification</th>
   <th scope="col">Status</th>
   <th scope="col">Comment</th>
  </tr>
  <tr>
   <td>{{SpecName('ESDraft', '#sec-delete-operator', 'The delete Operator')}}</td>
   <td>{{Spec2('ESDraft')}}</td>
   <td>&nbsp;</td>
  </tr>
  <tr>
   <td>{{SpecName('ES6', '#sec-delete-operator', 'The delete Operator')}}</td>
   <td>{{Spec2('ES6')}}</td>
   <td>&nbsp;</td>
  </tr>
  <tr>
   <td>{{SpecName('ES5.1', '#sec-11.4.1', 'The delete Operator')}}</td>
   <td>{{Spec2('ES5.1')}}</td>
   <td>&nbsp;</td>
  </tr>
  <tr>
   <td>{{SpecName('ES1', '#sec-11.4.1', 'The delete Operator')}}</td>
   <td>{{Spec2('ES1')}}</td>
   <td>Initial definition. Implemented in JavaScript 1.2.</td>
  </tr>
 </tbody>
</table>

<h2 id="Browser_compatibility">Browser compatibility</h2>

<p>{{CompatibilityTable}}</p>

<div id="compat-desktop">
<table class="compat-table">
 <tbody>
  <tr>
   <th>Feature</th>
   <th>Chrome</th>
   <th>Firefox (Gecko)</th>
   <th>Internet Explorer</th>
   <th>Opera</th>
   <th>Safari</th>
  </tr>
  <tr>
   <td>Basic support</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatVersionUnknown}}</td>
  </tr>
  <tr>
   <td>Temporal dead zone</td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatGeckoDesktop(36)}}</td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatUnknown}}</td>
  </tr>
 </tbody>
</table>
</div>

<div id="compat-mobile">
<table class="compat-table">
 <tbody>
  <tr>
   <th>Feature</th>
   <th>Android</th>
   <th>Chrome for Android</th>
   <th>Firefox Mobile (Gecko)</th>
   <th>IE Mobile</th>
   <th>Opera Mobile</th>
   <th>Safari Mobile</th>
  </tr>
  <tr>
   <td>Basic support</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatVersionUnknown}}</td>
  </tr>
  <tr>
   <td>Temporal dead zone</td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatGeckoMobile(36)}}</td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatUnknown}}</td>
  </tr>
 </tbody>
</table>
</div>

<h2 id="Cross-browser_notes">Cross-browser notes</h2>

<p>Although ECMAScript makes iteration order of objects implementation-dependent, it may appear that all major browsers support an iteration order based on the earliest added property coming first (at least for properties not on the prototype). However, in the case of Internet Explorer, when one uses <code>delete</code> 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 <em>value</em> is indeed set to undefined, if one later adds back a property with the same name, the property will be iterated in its <em>old</em> position--not at the end of the iteration sequence as one might expect after having deleted the property and then added it back.</p>

<p>So, if you want to simulate an ordered associative array in a cross-browser environment, you are forced to either use two separate arrays (one for the keys and the other for the values), or build an array of single-property objects, etc.</p>

<h2 id="See_also">See also</h2>

<ul>
 <li><a href="https://perfectionkills.com/understanding-delete/">In depth analysis on delete</a></li>
 <li>{{jsxref("Reflect.deleteProperty()")}}</li>
</ul>
Revert to this revision