SoFunction
Updated on 2025-03-01

Introduction to delete in Javascript

1. Problem raising

Let's first look at the following code. It should be noted that the following code should not be run in browser developer tools (such as FireBug, Chrome Developer tool). The reason will be explained later:

Why can we delete the properties of an object:
Copy the codeThe code is as follows:

var o = { x: 1 };
delete ; // true
; // undefined

But not to delete variables declared like this:
Copy the codeThe code is as follows:

var x = 1;
delete x; // false
x; // 1

Also, functions defined like this cannot be deleted:
Copy the codeThe code is as follows:

function x(){}
delete x; // false
typeof x; // "function"

Note: When the delete operator returns true, it means it can be deleted, and if it returns false, it means it cannot be deleted.

To understand this, we first need to master concepts such as variable instantiation and attribute characteristics - unfortunately, these contents are rarely mentioned in some JavaScript books. It's not difficult to understand them, and if you don't care why they run like this, you can skip this part at will.

2. Code type

There are three types of executable code in ECMAScript: Global code, Function code, and Eval code (code executed in Eval).
Copy the codeThe code is as follows:

var x=1;//Global code
function test(){
var y=2;//Function Code
eval("var z=3");//Eval Code in Function
}
eval("function evalTest(){}");//Eval Code in Global


3. Execution context

When ECMAScript code is executed, it always runs in a certain context, and the execution context is a somewhat abstract entity that helps us understand how scope and variable instantiation work. For three types of executable code, each has an execution context. When a function is executed, it can be said that control enters the execution context of the function code. When global code is executed, it enters the execution context of global code.

As you can see, the execution context logically comes from a stack. First of all, it may be global code with its own scope. A function may be called in the code, which has its own scope. The function can call another function, etc. Even if the function calls itself recursively, each call goes into a new execution context.

4. Activation object/Variable object

Each execution context has a Variable Object inside it. Similar to the execution context, Variable object is an abstract entity that describes the mechanism of variable instantiation. Interestingly, variables and functions declared in the code are actually added as properties of this variable object.

When entering the execution context of the global code, a global object is used as a variable object. This is precisely why variables or functions declared in the global scope become properties of the global object.
Copy the codeThe code is as follows:

/* remember that `this` refers to global object when in global scope */
var GLOBAL_OBJECT = this;

var foo = 1;
GLOBAL_OBJECT.foo; // 1
foo === GLOBAL_OBJECT.foo; // true

function bar(){}
typeof GLOBAL_OBJECT.bar; // "function"
GLOBAL_OBJECT.bar === bar; // true

Global variables become properties of global objects, but what about local variables defined in function code? The behavior is actually very similar: it becomes a property of a variable object. The only difference is that in the function code, the variable object is not a global object, but a so-called activation object. Each time the function code enters the execution scope, an activation object is created.

Not only are variables and functions in the function code (Function code) the properties of the activation object, but also each parameter of the function (the name corresponding to the formal parameter) and a specific Arguments object. Note that activation objects are an internal mechanism that will not be truly accessed by program code.
Copy the codeThe code is as follows:

(function(foo){

var bar = 2;
function baz(){}

/*
In abstract terms,

Special `arguments` object becomes a property of containing function's Activation object:
ACTIVATION_OBJECT.arguments; // Arguments object

...as well as argument `foo`:
ACTIVATION_OBJECT.foo; // 1

...as well as variable `bar`:
ACTIVATION_OBJECT.bar; // 2

...as well as function declared locally:
typeof ACTIVATION_OBJECT.baz; // "function"
*/

})(1);

Finally, the variable declared in the Eval code (Eval code) is created as the attribute of the variable object of the context being called. The Eval code (Eval code) uses only the variable object of which execution context it is being called.
Copy the codeThe code is as follows:

var GLOBAL_OBJECT = this;

/* `foo` is created as a property of calling context Variable object,
which in this case is a Global object */

eval('var foo = 1;');
GLOBAL_OBJECT.foo; // 1

(function(){

/* `bar` is created as a property of calling context Variable object,
which in this case is an Activation object of containing function */

eval('var bar = 1;');

/*
In abstract terms,
ACTIVATION_OBJECT.bar; // 1
*/

})();

V. Attributes
Now it is clear what happens to variables (they become attributes), and the only concept left to understand is attribute attribute properties. Each attribute has zero or more attributes from the following set of attributes - ReadOnly, DontEnum, DontDelete and Internal, you can think of them as a marker, an optional attribute. For the purposes of today's discussion, we only care about the DontDelete feature.

When declared variables and functions become attributes of a variable object - either an activation object (Function code) or a global object (Global code), these created attributes have the DontDelete attribute. However, any explicit (or implicit) created attribute does not have the DontDelete attribute. This is why some properties can be deleted, and some cannot.
Copy the codeThe code is as follows:

var GLOBAL_OBJECT = this;

/* `foo` is a property of a Global object.
It is created via variable declaration and so has DontDelete attribute.
This is why it can not be deleted. */

var foo = 1;
delete foo; // false
typeof foo; // "number"

/* `bar` is a property of a Global object.
It is created via function declaration and so has DontDelete attribute.
This is why it can not be deleted either. */

function bar(){}
delete bar; // false
typeof bar; // "function"

/* `baz` is also a property of a Global object.
However, it is created via property assignment and so has no DontDelete attribute.
This is why it can be deleted. */

GLOBAL_OBJECT.baz = 'blah';
delete GLOBAL_OBJECT.baz; // true
typeof GLOBAL_OBJECT.baz; // "undefined"


6. Built-in properties and DontDelete

In a word: A unique feature in the attribute (DontDelete) controls whether this attribute can be deleted. Note that the built-in properties of an object (i.e., the predefined properties of the object) have the DontDelete property and therefore cannot be deleted. A specific Arguments variable (or, as we now know, the activation of an object's properties), the length property of any function instance also has the DontDelete property.
Copy the codeThe code is as follows:

(function(){

/* can't delete `arguments`, since it has DontDelete */

delete arguments; // false
typeof arguments; // "object"

/* can't delete function's `length`; it also has DontDelete */

function f(){}
delete ; // false
typeof ; // "number"

})();

The created attributes corresponding to the function parameters also have the DontDelete property, so they cannot be deleted.
Copy the codeThe code is as follows:

(function(foo, bar){

delete foo; // false
foo; // 1

delete bar; // false
bar; // 'blah'

})(1, 'blah');


7. Undeclared assignment

Simply, an undeclared assignment creates a deleteable property on a global object.
Copy the codeThe code is as follows:

var GLOBAL_OBJECT = this;

/* create global property via variable declaration; property has DontDelete */
var foo = 1;

/* create global property via undeclared assignment; property has no DontDelete */
bar = 2;//It can be understood as =2; according to the fifth point above, it can be deleted

delete foo; // false
typeof foo; // "number"

delete bar; // true
typeof bar; // "undefined"

Please note that the DontDelete attribute is determined during the creation of the attribute, and later assignments will not modify the existing attributes already exist. It is important to understand this.
Copy the codeThe code is as follows:

/* `foo` is created as a property with DontDelete */
function foo(){}

/* Later assignments do not modify attributes. DontDelete is still there! */
foo = 1;
delete foo; // false
typeof foo; // "number"

/* But assigning to a property that doesn't exist,
creates that property with empty attributes (and so without DontDelete) */

= 1;
delete bar; // true
typeof bar; // "undefined"

Eval code
Variables or methods created in Eval are more special and do not have the DontDelete feature, which means they can be deleted.

Copy the codeThe code is as follows:

eval("var x = 1;");
(x); // 1
delete x;
(typeof x); // undefined

eval("function test(){ var x=1; (delete x);/* false */;return 1;}");
(test()); // 1
delete test;
(typeof test); // undefined

Note that the variables or methods created in Eval mentioned here do not include variables or methods inside the method. For example, the red part in the above code is still the same as what I said before: they cannot be deleted.

9. FireBug's confusion

Let's look at the result of a code executed in FireBug:
Copy the codeThe code is as follows:

var x=1;
delete x;
(typeof x);//undefined

function y(){
var z=1;
(delete z);//false
}
y();
delete y;
(typeof y);//undefined

This obviously violates the above rules, but after comparing it with the eighth point above, it is found that this is the effect of the code being executed in eval. Although not confirmed, I guess the console code in FireBug (Chrome Developer tool) is executed with eval.

Therefore, when testing JS code, you should pay special attention when it comes to the current context.

10. Objects deleted by delete operator

There is also a delete operator in C++, which deletes the object pointed to by the pointer. For example:

Copy the codeThe code is as follows:

class Object {
public:
Object *x;
}

Object o;
= new Object();
delete ; // The object object in the previous line new will be released

But Javascript's delete is different from C++, it does not delete the object pointed to, but deletes the property itself.
Copy the codeThe code is as follows:

var o = {};
= new Object();
delete ; // The object object in the previous line new still exists
; // undefined, the attribute named x of o has been deleted

In actual Javascript, after delete, the Object object will be garbage collected due to loss of reference, so delete is "equivalent to" deleting the object pointed to, but this action is not the ECMAScript standard. That is to say, even if an implementation does not delete the Object object at all, it is not considered a violation of the ECMAScript standard.

"Delete attributes instead of delete objects" can be confirmed by the following code.
Copy the codeThe code is as follows:

var o = {};
var a = { x: 10 };
= a;
delete ; // The attribute is deleted
; // undefined
; // 10, because the { x: 10 } object is still referenced by a, so it will not be recycled

In addition, delete can also be written as delete o["x"], and the effects of both are the same.

11. Other attributes that cannot be deleted

In addition to the built-in properties (i.e. predefined properties) mentioned above, the properties declared in the prototype cannot be deleted:
Copy the codeThe code is as follows:

function C() { = 42; }
= 12;
= 13;

var o = new C();
; // 42, defined in the constructor

delete ; //true deletes the x defined by itself
; // 12, defined in prototype, even if delete is executed again, it will not be deleted

delete; //true, because o has no attributes, y exists in the prototype chain, that is, the object's own attributes and prototype attributes are different
; //13


summary

I have said so much above, I hope it will be helpful for everyone to understand Delete in JavaScript. Due to limited levels, it is not guaranteed to be completely correct. If you find any errors, please feel free to correct them.

Original text is:
1、/understanding-delete/(English)
2、/blog/2008/01/09/2552470(Japanese)

This article was first published