first, the question of the proposed
Let's take a look at the following code, and note that the following code does not run in the browser's developer tool (such as Firebug, Chrome Developer tool), which is explained later:
Why we can delete an object's properties:
Copy Code code as follows:
var o = {x:1};
Delete o.x; True
o.x; Undefined
But not to delete variables such as these declared:
Copy Code code as follows:
var x = 1;
Delete x; False
X 1
You cannot delete a function that is defined like this:
Copy Code code as follows:
function X () {}
Delete x; False
typeof X; "Function"
Note: When the delete operator returns true, it can be deleted, and the return false indicates that it cannot be deleted
To understand this, we first need to grasp concepts such as variable instantiation and attribute attributes-which, sadly, are rarely mentioned in some JavaScript books. It's not difficult to understand them, and if you don't care why they're running, you can skip this part at random.
second, code type
There are three types of executable code in ECMAScript: Global Code (globally), function code (function codes), and eval code, which is executed in eval.
Copy Code code 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
Iii. Execution Context
When ECMAScript code executes, it always runs in a certain context, and the execution context is a somewhat abstract entity that helps us understand how scopes and variable instantiations work. For three types of executable code, each has a context for execution. When a function executes, it can be said that control enters the execution context of the function code. When the global code executes, it enters the execution context of global code.
As you can see, the execution context logically comes from a stack. The first may be the global code with its own scope, which may call a function, it has its own scope, the function can call another function, and so on. Each call enters a new execution context, even if the function recursively calls itself.
Activation Object (active object)/variable object (Variable objects)
Each execution context has a variable Object inside it. Like the execution context, Variable object is an abstract entity used to describe the mechanism of variable instantiation. Interestingly, the variables and functions declared in the code are actually added as properties of the variable object.
When you enter the execution context of the global Code, a global object is used as the variable object. This is why the variables or functions declared in the global scope become the properties of the global object.
Copy Code code as follows:
/* Remember that "this" refers to the global object 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 that are defined in function code? Behavior is very similar: it becomes the property of the Variable object. The only difference is that in function code, the variable object is not a global object, but rather a so-called activation object (activation object). Each time the function code is entered into the execution scope, an Activation object (activation object) is created.
Not only are variables and functions in the function code, which are the properties of the active object, but also each parameter of the function (the name corresponding to the formal parameter) and a specific arguments object. Note that the activation object is an internal mechanism that is not actually accessed by the program code.
Copy Code code 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-as-argument ' foo ':
Activation_object.foo; 1
... as-as-variable ' bar ':
Activation_object.bar; 2
-As-as-function declared locally:
typeof Activation_object.baz; "Function"
*/
}) (1);
Finally, the variable declared in the eval code is created as the property of the variable object of the context being invoked. The eval code uses only the variable object of which execution context it is being invoked.
Copy Code code as follows:
var global_object = this;
/* ' foo ' is created as a-calling context Variable object,
Which in the case is a Global object * *
Eval (' var foo = 1; ');
Global_object.foo; 1
(function () {
/* ' Bar ' is created as a-calling context Variable object,
Which in the case being an activation object of containing function */
Eval (' var bar = 1; ');
/*
In abstract terms,
Activation_object.bar; 1
*/
})();
v. Property characteristics
Now that the variables will be clear (they become attributes), the only thing left to understand is the attribute attribute. Each property has 0 or more attributes from one of the following set of properties--readonly, Dontenum, dontdelete and internal, you can think of as a tag, an attribute that is dispensable. For the purpose of today's discussion, we only care about dontdelete characteristics.
When declared variables and functions become properties of a variable object-either an Activation object (function code), or a global object (global Code), these properties are created with the Dontdelete attribute. However, any explicitly (or implicitly) created property does not have a dontdelete attribute. That's why some attributes can be removed, some cannot.
Copy Code code 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 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 deleted either. */
function bar () {}
Delete bar; False
typeof Bar; "Function"
/* ' Baz ' is also a property of a Global object.
However, it is created via the 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"
Vi. Built-in properties and Dontdelete
In a word: a unique attribute (Dontdelete) controls whether this property can be deleted. Note that the object's built-in properties (that is, the object's predefined properties) have Dontdelete attributes and cannot be deleted. A specific arguments variable (or, as we now know, activates an object's properties), the length property of any function instance also has a Dontdelete attribute.
Copy Code code 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 f.length; False
typeof F.length; "Number"
})();
The created property corresponding to the function parameter also has a Dontdelete attribute, and therefore cannot be deleted.
Copy Code code as follows:
(Function (foo, bar) {
Delete foo; False
Foo 1
Delete bar; False
Bar ' Blah '
}) (1, ' blah ');
Vii. Unspecified Assignments
Simply, an undeclared assignment creates a removable property on a global object.
Copy Code code 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;//can be understood as window.bar=2; According to the 5th above, it can be deleted.
Delete foo; False
typeof Foo; "Number"
Delete bar; True
typeof Bar; "Undefined"
Note that it is important to understand that the Dontdelete attribute is determined in the process of creating a property, and that subsequent assignments do not modify the existing attributes of a property that already exists.
Copy Code code as follows:
/* ' foo ' is created as a and dontdelete * *
function foo () {}
/* Later assignments does 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) * *
This.bar = 1;
Delete bar; True
typeof Bar; "Undefined"
Eight, Eval code
The variables or methods created in Eval are special, with no dontdelete attributes, which means they can be deleted.
Copy Code code as follows:
Eval ("var x = 1;");
Console.log (x); 1
Delete x;
Console.log (typeof x); Undefined
Eval ("function test () {var x=1; Console.log (delete x);/* false */;return 1;} ");
Console.log (Test ()); 1
Delete test;
Console.log (typeof test); Undefined
Note that the variable or method created in eval does not include a variable or method inside the method, such as the red part of the code above, which is still consistent with what was said before: cannot be deleted.
ix. the perplexity of Firebug
Let's take a look at the code results executed in Firebug:
Copy Code code as follows:
var x=1;
Delete x;
Console.log (typeof x);//undefined
function Y () {
var z=1;
Console.log (delete z);//false
}
Y ();
Delete y;
Console.log (typeof y);//undefined
This is clearly a violation of the above rules, but in contrast to the 8th above it is found that this is the effect that the code performs in the eval. Although not confirmed, I suspect that the console code in Firebug (Chrome Developer tool) is executed with Eval.
So, when you are testing the JS code, if the current context is involved in particular attention.
10, delete operator deleted object
C + + also has the delete operator, which deletes the object that the pointer points to. For example:
Copy Code code as follows:
Class Object {
Public
Object *x;
}
Object o;
o.x = new Object ();
Delete o.x; Object on line new will be freed
But the JavaScript delete is different from C + +, it does not delete the object that o.x points to, but deletes the O.x property itself.
Copy Code code as follows:
var o = {};
o.x = new Object ();
Delete o.x; The object object of the previous line new is still present
o.x; Undefined,o's attribute named X is deleted.
In actual JavaScript, after delete o.x, object objects are garbage collected because they are lost, so the delete o.x is "equivalent" to deleting the object pointed to by o.x, but this action is not ECMAScript standard, that is to say, Even if an implementation does not delete object objects at all, it is not a violation of the ECMAScript standard.
"Delete attributes instead of deleting objects" can be confirmed by the following code.
Copy Code code as follows:
var o = {};
var a = {x:10};
O.A = A;
Delete o.a; O.a property is deleted
O.A; Undefined
a.x; 10 because the {X:10} object is still referenced by a, so it will not be reclaimed
In addition, the delete o.x can write the delete o["X", both of which have the same effect.
11, other properties that cannot be deleted
The properties declared in prototype cannot be deleted except for the built-in attributes (that is, predefined properties) that are mentioned above.
Copy Code code as follows:
function C () {this.x = 42;}
c.prototype.x = 12;
C.PROTOTYPE.Y = 13;
var o = new C ();
o.x; 42, the o.x defined in the constructor
Delete o.x; True deletes the x that is defined by itself
o.x; The o.x defined in prototype is not deleted even if the delete o.x is executed again
Delete o.y; True, because O itself has no o.y attribute, Y exists in the prototype chain, which means that the object itself and the prototype property are different
O.Y; 13
Summary
That's a lot to say, and I want to help you understand the delete in JavaScript. Due to the limited level, it is not guaranteed to be completely correct, if found wrong welcome correction.
The original text is:
1, http://perfectionkills.com/understanding-delete/(English)
2, http://nanto.asablo.jp/blog/2008/01/09/2552470 (Japanese)
This article starts http://jscode.cnblogs.com