The delete in Javascript has not been quite clear. Recently I have seen two articles about this.ArticleThe two sections are now translated (the content has been modified and added, and the order is not completely the same. If you are interested, please refer to the original article). I hope this will help you.
Original:
1. http://perfectionkills.com/understanding-delete)
2. http://nanto.asablo.jp/blog/2008/01/09/2552470 (Japanese)
Note: This first blog Park (http://jscode.cnblogs.com/), reprint must give the original link.
I. Question proposal
Let's take a look at the following paragraphs.Code,Note that the following code should not be run in browser developer tools (such as firebug and chrome developer tool ).:
Why can we delete the attributes of an object:
VaRO = {X: 1};DeleteO. X;//TrueO. X;//Undefined
But do not delete the variables declared like this:
VaRX = 1;DeleteX;//FalseX;//1
You cannot delete a function defined as follows:
FunctionX (){}DeleteX;//FalseTypeofX;//"Function"
Note: When the delete operator returns true, the operation can be deleted. If the delete operator returns false, the operation cannot be deleted.
To understand this, we need to first master the concepts such as variable instantiation and attribute features-unfortunately, these contents are rarely mentioned in some JavaScript books. It is not difficult to understand them. If you don't care why they are running, you can skip this part at will.
Ii. Code Type
There are three types of executable code in ecmascript: Global Code, function code, and eval code ).
VaRX = 1;//Global CodeFunctionTest (){VaRY = 2;//Function CodeEval ("Var z = 3 ");//Eval code in Function} Eval ("Function evaltest (){}");//Eval code in global
Iii. Execution Context
When ecmascript code is executed, it always runs in a certain context. The execution context is a somewhat abstract entity, which helps us understand how the 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 the control enters the execution context of the function code. The Global Code Execution context is displayed.
As you can see, the execution context logic comes from a stack. First, there may be a global code with its own scope. The Code may call a function, which has its own scope, and the function can call another function. Even if a function recursively calls itself, each call enters a new execution context.
4. Activation object/variable object)
Each execution context has a variable object within it. Similar to 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 attributes of the variable object.
When the execution context of the global code is entered, a global object is used as a variable object. This is exactly why the variables or functions declared in the global scope become the attributes of the global object.
/* remember that 'eas' 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
The global variable becomes the attribute of the global object. But what about the local variables defined in the function code? The behavior is actually very similar: it becomes the property of the variable object. The only difference is that in function code, variable objects are called activation objects instead of global objects ). Every time the Function Code enters the execution scope, an activation object is created ).
Not only do variables and functions in Function Code become the attributes of the activated object, but also each parameter (name corresponding to the form parameter) of the function and a specific arguments object. Note that activating an object is an internal mechanism and will not beProgramThe code is actually accessed.
(Function(FOO ){VaRBar = 2;FunctionBaz (){}/*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 variables declared in the eval code are created as attributes of the variable object in the context of the call. The eval Code only uses the variable object of the execution context in which it is called.
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. Attribute features
Now the variables are clear (they become attributes), and the only concept to be understood is the attribute feature. Each attribute has zero or multiple features from one of the following attributes-readonly, dontenum, dontdelete, and internal. You can think of them as a tag and an attribute as dispensable. For the purpose of today's discussion, we only care about the dontdelete feature.
When declared variables and functions become attributes of a variable object, they are either function code or Global Code. These created attributes have the dontdelete feature. However,Any explicitly (or implicitly) created attribute does not have the dontdelete feature.This is why some of our attributes can be deleted, and some cannot.
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"
Vi. built-in attributes and dontdelete
In a word, a unique attribute (dontdelete) controls whether this attribute can be deleted. Note,The built-in attributes of an object (that is, the predefined attributes of an object) have the dontdelete feature, so they cannot be deleted.For specific arguments variables (or, as we know now, activating object attributes), The Length attribute of any function instance also has the dontdelete feature.
( 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 attributes corresponding to function parameters also have the dontdelete feature, so they cannot be deleted.
(Function(Foo, bar ){DeleteFoo;//FalseFoo;//1DeleteBar;//FalseBar;//'Blah'})(1, 'blah ');
7. Undeclared assignment
Simply put, an undeclared value is used to create a deletable attribute on a global object.
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 window. bar = 2; it can be deleted according to the fifth point above. Delete Foo; // False Typeof Foo; // "Number" Delete Bar; // True Typeof Bar; // "Undefined"
Please note that,The dontdelete feature is determined during the attribute creation process. The subsequent assignment does not modify the existing attributes.It is important to understand this.
/* '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) */ This . Bar = 1 ; Delete Bar; // True Typeof Bar; // "Undefined"
VIII. Eval code
Variables or methods created in eval are special. They do not have the dontdelete feature, that is, they can be deleted.
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,Variables or methods created in eval do not include variables or methods in the method., As shown in the red part of the code above, it is still the same as previously mentioned: it cannot be deleted.
9. firebug confusions
Let's take a look at the code execution results in firebug:
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 clearly violates the above rules, but compared with the above eight points, we found that this is the effect of code execution in eval. Although not confirmed, I guess the console code in firebug (chrome developer tool) is executed using eval.
Therefore, when testing JavaScript code, pay special attention to the current context.
10. Objects deleted by the delete Operator
C ++ also has the delete operator, which deletes the object pointed to by the pointer. For example:
ClassObject {Public: Object*X;} object O; O. X=NewObject (); Delete O. X;//The new object in the previous row will be released.
However, unlike C ++, JavaScript Delete does not delete the objects pointed to by O. X, but deletes the o. x attribute itself.
VaRO ={}; O. x=NewObject ();DeleteO. X;//The new object in the previous Row still exists.O. X;//Undefined, O's property named X has been deleted
In actual JavaScript, delete O. after X, the object will be reclaimed due to the loss of reference, So delete O. X is equivalent to deleting O. X points to the object, but this action is not the ecmascript standard. That is to say, even if an implementation does not delete the object at all, it is not in violation of the ecmascript standard.
"Delete attributes instead of ObjectsThis can be confirmed through the following code.
VaRO ={};VaRA = {X: 10}; O.=A;DeleteO.;//O. A property is deletedO.;//UndefinedA. X;//10. Because the {X: 10} object is still referenced by a, it will not be recycled.
In addition, delete o. x can also write Delete o ["X"], with the same effect.
11. Other attributes that cannot be deleted
Except that the built-in attributes (pre-defined attributes) mentioned above cannot be deleted,The attribute declared in prototype cannot be deleted.:
Function C (){ This . X = 42;} C. Prototype. x = 12 C. Prototype. Y = 13 ; VaR O = New C (); O. X; // 42. o. x defined in the constructor Delete O. X; // True deletes x defined by the user. O. X; // 12. o. x defined in prototype will not be deleted even if Delete O. X is executed again. Delete O. Y;// True: Because o does not have the O. Y attribute, y exists in the prototype chain. That is to say, the attributes of the object are different from those of prototype. O. Y; // 13
Summary
As mentioned above, I hope to help you understand delete In JavaScript. Due to the limited level, it is not guaranteed to be completely correct. If any error is found, please correct it.
This article first blog Garden (http://jscode.cnblogs.com/), content may be corrected, welcome to my blog comment.