Patient said:
Patient Guy wrote:
I have to follow up to my own post unfortunately, because
I am sure I will get upbraided by a few hair-splitters for
an improper use of terms here.
I don't think we will be splitting hairs here, you are so far off the
mark that you have posted a fantasy of VKesque proportions.
I did say that the 'delete' operator was a destructor, and
I believe in the most technical way, that is wrong.
Yes it is. Given your proposal that - delete - operations should have a
one-to-one relationship with - new - operations I assume you are
viewing - delete - as directly (or actively) resulting in the
destruction of an object created with the - new - operator and assigned
to an object property or variable. I.E.:-
var something = new Somethong();
- and:-
delete something;
- would act upon the object resulting from the - new Something() -
expression. It does not. It acts upon the object in the scope chain on
which 'something' is a named property. The ECMA 262 algorithm for -
delete is:-
<quote cite="ECMA 262, 3rd Ed. section 11.4.1">
11.4.1 The delete Operator
The production UnaryExpression : delete UnaryExpression is
evaluated as follows:
1. Evaluate UnaryExpression.
2. If Type(Result(1)) is not Reference, return true.
3. Call GetBase(Result(1)).
4. Call GetPropertyName(Result(1)).
5. Call the [[Delete]] method on Result(3), providing Result(4) as
the property name to delete.
6. Return Result(5).
</quote>
The UnaryExpression evaluated in the first step (in - delete
something; - following - var something = new Something()
is the
unqualified Identifier - something -, which is resolved against the
scope chain in accordance with ECMA 262 (assume 3rd edition from now on)
Section 10.1.4, which always produces a Reference type, so step 2 is
fine. Step 3 retrieves the 'Base' object from that Reference type, which
is either the global object (if the variable was declared in the global
scope) or is a Variable object (if it is a function local variable).
The property named retrieved in step 4 is the string "something", and so
step 5 calls the internal [[Delete]] method of the global/variable
object, passing "something" as the name of the property to delete. The
algorithm for - [[Delete]] is:-
<quote cite="ECMA 262, 3rd Ed. section 8.6.5">
8.6.2.5 [[Delete]] (P)
When the [[Delete]] method of O is called with property name P, the
following steps are taken:
1. If O doesn't have a property with name P, return true.
2. If the property has the DontDelete attribute, return false.
3. Remove the property with name P from O.
4. Return true.
</quote>
So you might expect that the property of the global/Variable object with
the name "something" will be removed from the global/Variable object.
Now the property of the global/Variable object with the name "something"
had been assigned a value that is a reference to the object created
with - new Something() - so the act of removing the property from the
global/variable object will remove that reference from the system. This
is where memory management does come into the picture. Javascript uses
automatic garbage collection and when there are no longer any accessible
references to an object that object becomes eligible from garbage
collection (at some undeterminable future time). If the "something"
property of the global/Variable object was removed it would no longer
refer to the constructed object, and if its value had been the only
reference to that object then that object becomes available for garbage
collection.
However, step 2 in the [[Delete]] algorithm checks to see if the
property that is to be deleted has the internal DontDelete attribute,
and if it does is does not act (the property is not removed).
The "something" property of the global/Variable object was created as a
result of a variable declaration, subject to sections 10.1.3, 10.2.1 and
10.2.3 of the specification, where we find:-
<quote cite="ECMA 262, 3rd Ed. section 10.2.1">
10.2.1 Global Code
....
Variable instantiation is performed using the global object as the
variable object and using property attributes { DontDelete }.
....
</quote>
<quote cite="ECMA 262, 3rd Ed. section 10.2.3">
10.2.3 Function Code
....
Variable instantiation is performed using the activation object as
the variable object and using property attributes { DontDelete }.
....
</quote>
- and see that the DontDelete attribute is set on all declared global
and function local variables (except those declared within an - eval -
function call).
And so given:-
var something = new Something();
- doing:-
delete something;
- will be ineffective, it will not result in the removal of the property
of the global/Variable object, and so it will not result in the removal
of the value of that property that refers to the object constructed
with - new Something() -, and while the reference to the object remains
the constructed object cannot be garbage collection, and will continue
to consume memory. Thus the proposal that - delete - should be used in
order to free references to objects so that their memory could be
released during garbage collection is almost the reverse of good advice.
Indeed, because the "something" property has a value that is a reference
to an object, the act of assigning a different value to that property
will result in the removal of the pre-existing reference from the
system, reliably. And so:-
something = null;
- is a better alternative because it will prevent - something - from
referring to the constructed object.
There is a high probability now that more will be said,
if only because I expanded on my self-doubts here.
;-)
Richard.