Perfection Kills

by kangax

Exploring Javascript by example

Understanding delete

January 10th, 2010
  1. Theory

  2. Firebug confusion

  3. Browsers compliance

  4. IE bugs
  5. Misconceptions
  6. `delete` and host objects
  7. ES5 strict mode
  8. Summary

A couple of weeks ago, I had a chance to glance through Stoyan Stefanov’s Object-Oriented Javascript. The book had an exceptionally high rating on Amazon (12 reviews with 5 stars), so I was curious to see if it was something worth recommending. I started reading through chapter on functions, and really enjoyed the way things were explained there; the flow of examples was structured in such nice, progressive way, it seemed even beginners would grasp it easily. However, almost immediately I stumbled upon an interesting misconception present throughout the entire chapter — deleting functions. There were some other mistakes (such as the difference between function declarations and function expressions), but we aren’t going to talk about them now.

The book claims that “function is treated as a normal variable—it can be copied to a different variable and even deleted.”. Following that explanation, there is this example:


  >>> var sum = function(a, b) {return a + b;}
  >>> var add = sum;
  >>> delete sum
  true
  >>> typeof sum;
  "undefined"
  

Ignoring a couple of missing semicolons, can you see what’s wrong with this snippet? The problem, of course, is that deleting sum variable should not be successful; delete statement should not evaluate to true and typeof sum should not result in “undefined”. All because it’s not possible to delete variables in Javascript. At least not when declared in such way.

So what’s going on in this example? Is it a typo? A diversion? Probably not. This whole snippet is actually a real output from the Firebug console, which Stoyan must have been using for quick testing. It’s almost as if Firebug follows some other rules of deletion. It is Firebug that has led Stoyan astray! So what is really going on here?

To answer this question, we need to understand how delete operator works in Javascript: what exactly can and cannot be deleted and why. Today I’ll try to explain this in details. We’ll take a look at Firebug’s “weird” behavior and realize that it’s not all that weird; we’ll delve into what’s going on behind the scenes when declaring variables, functions, assigning properties and deleting them; we’ll look at browsers’ compliance and some of the most notorious bugs; we’ll also talk about strict mode of 5th edition of ECMAScript, and how it changes delete operator behavior.

I’ll be using Javascript and ECMAScript interchangeable to really mean ECMAScript (unless explicitly talking about Mozilla’s JavaScript™ implementation).

Unsurprisingly, explanations of delete on the web are rather scarce. MDC article is probably the most comprehensive resource, but unfortunately misses few interesting details about the subject; Curiously, one of these forgotten things is the cause of Firebug’s tricky behavior. MSDN reference is practically useless.

Theory

So why is it that we can delete object properties:


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

but not variables, declared like this:


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

or functions, declared like this:


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

Note that delete only returns false when a property can not be deleted.

To understand this, we need to first grasp such concepts as variable instantiation and property attributes — something that’s unfortunately rarely covered in books on Javascript. I’ll try go over these very concisely in the next few paragraphs. It’s not hard to understand them at all! If you don’t care about why things work the way they work, feel free to skip this chapter.

Type of code

There are 3 types of executable code in ECMAScript: Global code, Function code and Eval code. These types are somewhat self-descriptive, but here’s a short overview:

  1. When a source text is treated as a Program, it is executed in a global scope, and is considered a Global code. In a browser environment, content of SCRIPT elements is usually parsed as a Program, and is therefore evaluated as a Global code.
  2. Anything that’s executed directly within a function is, quite obviously, considered a Function code. In browsers, content of event attributes (e.g. <p onclick="...">) is usually parsed and treated as a Function code.
  3. Finally, text that’s supplied to a built-in eval function is parsed as Eval code. We will soon see why this type is special.

Execution context

When ECMAScript code executes, it always happens within certain execution context. Execution context is a somewhat abstract entity, which helps understand how scope and variable instantiation works. For each of three types of executable code, there’s an execution context. When a function is executed, it is said that control enters execution context for Function code; when Global code executes, control enters execution context for Global code, and so on.

As you can see, execution contexts can logically form a stack. First there might be Global code with its own execution context; that code might call a function, with its own execution context; that function could call another function, and so on and so forth. Even if function is calling itself recursively, a new execition context is being entered with every invocation.

Activation object / Variable object

Every execution context has a so-called Variable Object associated with it. Similarly to execution context, Variable object is an abstract entity, a mechanism to describe variable instantiation. Now, the interesing part is that variables and functions declared in a source text are actually added as properties of this Variable object.

When control enters execution context for Global code, a Global object is used as a Variable object. This is precisely why variables or functions declared globally become properties of a Global object:


  /* 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
  

Ok, so global variables become properties of Global object, but what happens with local variables — those declared in Function code? The behavior is actually very similar: they become properties of Variable object. The only difference is that when in Function code, a Variable object is not a Global object, but a so-called Activation object. Activation object is created every time execution context for Function code is entered.

Not only do variables and functions declared within Function code become properties of Activation object; this also happens with each of function arguments (under names corresponding to formal parameters) and a special Arguments object (under arguments name). Note that Activation object is an internal mechanism and is never really accessible by program code.


  (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, variables declared within Eval code are created as properties of calling context’s Variable object. Eval code simply uses Variable object of the execution context that it’s being called within:


  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
    */

  })();
  

Property attributes

We are almost there. Now that it’s clear what happens with variables (they become properties), the only remaining concept to understand is property attributes. Every property can have zero or more attributes from the following set — ReadOnly, DontEnum, DontDelete and Internal. You can think of them as flags — an attribute can either exist on a property or not. For the purposes of today’s discussion, we are only interested in DontDelete.

When declared variables and functions become properties of a Variable object — either Activation object (for Function code), or Global object (for Global code), these properties are created with DontDelete attribute. However, any explicit (or implicit) property assignment creates property without DontDelete attribute. And this is essentialy why we can delete some properties, but not others:


  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"
  

Built-ins and DontDelete

So this is what it’s all about: a special attribute on a property that controls whether this property can be deleted or not. Note that some of the properties of built-in objects are specified to have DontDelete, and so can not be deleted. Special arguments variable (or, as we know now, a property of Activation object) has DontDelete. length property of any function instance has DontDelete as well:


  (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"

  })();
  

Properties corresponding to function arguments are created with DontDelete as well, and so can not be deleted either:


  (function(foo, bar){

    delete foo; // false
    foo; // 1

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

  })(1, 'blah');
  

Undeclared assignments

As you might remember, undeclared assignment creates a property on a global object. That is unless that property is found somewhere in the scope chain before global object. And now that we know the difference between property assignment and variable declaration — latter one sets DontDelete, whereas former one doesn’t — it should be clear why undeclared assignment creates a deletable property:


  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;

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

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

Note that it is during property creation that attributes are determined (i.e. none are set). Later assignments don’t modify attributes of existing property. It’s important to understand this distinction.


  /* `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"

Firebug confusion

So what happens in Firebug? Why is it that variables declared in console can be deleted, contrary to what we have just learned? Well, as I said before, Eval code has a special behavior when it comes to variable declaration. Variables declared within Eval code are actually created as properties without DontDelete:


  eval('var foo = 1;');
  foo; // 1
  delete foo; // true
  typeof foo; // "undefined"
  

and, similarly, when called within Function code:


  (function(){

    eval('var foo = 1;');
    foo; // 1
    delete foo; // true
    typeof foo; // "undefined"

  })();
  

And this is the gist of Firebug’s abnormal behavior. All the text in console seems to be parsed and executed as Eval code, not as a Global or Function one. Obviously, any declared variables end up as properties without DontDelete, and so can be easily deleted. Be aware of these differences between regular Global code and Firebug console.

Deleting variables via eval

This interesting eval behavior, coupled with another aspect of ECMAScript can technically allow us to delete non-deletable properties. The thing about function declarations is that they can overwrite same-named variables in the same execution context:


  function x(){ }
  var x;
  typeof x; // "function"
  

Note how function declaration takes precedence and overwrites same-named variable (or, in other words, same property of Variable object). This is because function declarations are instantiated after variable declarations, and are allowed to overwrite them. Not only does function declaration replaces previous value of a property, it also replaces that property attributes. If we declare function via eval, that function should also replace that property’s attributes with its own. And since variables declared from within eval create properties without DontDelete, instantiating this new function should essentially remove existing DontDelete attribute from the property in question, making that property deletable (and of course changing its value to reference newly created function).


  var x = 1;

  /* Can't delete, `x` has DontDelete */

  delete x; // false
  typeof x; // "number"

  eval('function x(){}');

  /* `x` property now references function, and should have no DontDelete */

  typeof x; // "function"
  delete x; // should be `true`
  typeof x; // should be "undefined"
  

Unfortunately, this kind of spoofing doesn’t work in any implementation I tried. I might be missing something here, or this behavior might simply be too obscure for implementors to pay attention to.

Browsers compliance

Knowing how things work in theory is useful, but practical implications are paramount. Do browsers follow standards when it comes to variable/property creation/deletion? For the most part, yes.

I wrote a simple test suite to check compliance of delete operator with Global code, Function code and Eval code. Test suite checks both — return value of delete operator, and whether properties are deleted (or not) as they are supposed to. delete return value is not as important as its actual results. It’s not very crucial if delete returns true instead of false, but it’s important that properties with DontDelete are not deleted and vice versa.

Modern browsers are generally pretty compliant. Besides this eval peculiarity I mentioned earlier, the following browsers pass test suite fully: Opera 7.54+, Firefox 1.0+, Safari 3.1.2+, Chrome 4+.

Safari 2.x and 3.0.4 have problems with deleting function arguments; those properties seem to be created without DontDelete, so it is possible to delete them. Safari 2.x has even more problems — deleting non-reference (e.g. delete 1) throws error; function declarations create deletable properties (but, strangely, not variable declarations); variable declarations in eval become non-deletable (but not function declarations).

Similar to Safari, Konqueror (3.5, but not 4.3) throws error when deleting non-reference (e.g. delete 1) and erroneously makes function arguments deletable.

Gecko DontDelete bug

Gecko 1.8.x browsers — Firefox 2.x, Camino 1.x, Seamonkey 1.x, etc. — exhibit an interesting bug where explicitly assigning to a property can remove its DontDelete attribite, even if that property was created via variable or function declaration:


    function foo(){}
    delete foo; // false (as expected)
    typeof foo; // "function" (as expected)

    /* now assign to a property explicitly */

    this.foo = 1; // erroneously clears DontDelete attribute
    delete foo; // true
    typeof foo; // "undefined"

    /* note that this doesn't happen when assigning property implicitly */

    function bar(){}
    bar = 1;
    delete bar; // false
    typeof bar; // "number" (although assignment replaced property)
  

Surprisingly, Internet Explorer 5.5 – 8 passes test suite fully except that deleting non-reference (e.g. delete 1) throws error (just like in older Safari). But there are actually more serious bugs in IE, that are not immediately apparent. These bugs are related to Global object.

IE bugs

The entire chapter just for bugs in Internet Explorer? How unexpected!

In IE (at least, 6-8), the following expression throws error (when evaluated in Global code):


    this.x = 1;
    delete x; // TypeError: Object doesn't support this action
  

and this one as well, but different exception, just to make things interesting:


    var x = 1;
    delete this.x; // TypeError: Cannot delete 'this.x'
  

It’s as if variable declarations in Global code do not create properties on Global object in IE. Creating property via assignment (this.x = 1) and then deleting it via delete x throws error. Creating property via declaration (var x = 1) and then deleting it via delete this.x throws another error.

But that’s not all. Creating property via explicit assignment actually always throws error on deletion. Not only is there an error, but created property appears to have DontDelete set on it, which of course it shouldn’t have:


    this.x = 1;

    delete this.x; // TypeError: Object doesn't support this action
    typeof x; // "number" (still exists, wasn't deleted as it should have been!)

    delete x; // TypeError: Object doesn't support this action
    typeof x; // "number" (wasn't deleted again)
  

Now, contrary to what one would think, undeclared assignments (those that should create a property on global object) do create deletable properties in IE:


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

But if you try to delete such property by referecing it via this in Global code (delete this.x), a familiar error pops up:


    x = 1;
    delete this.x; // TypeError: Cannot delete 'this.x'
  

If we were to generalize this behavior, it would appear that delete this.x from within Global code never succeeds. When property in question is created via explicit assignment (this.x = 1), delete throws one error; when property is created via undeclared assignment (x = 1) or via declaration (var x = 1), delete throws another error.

delete x, on the other hand, only throws error when property in question is created via explicit assignment — this.x = 1. If a property is created via declaration (var x = 1), deletion simply never occurs and delete correctly returns false. If a property is created via undeclared assignment (x = 1), deletion works as expected.

I was pondering about this issue back in September, and Garrett Smith suggested that in IE “The global variable object is implemented as a JScript object, and the global object is implemented by the host. Garrett used Eric Lippert’s blog entry as a reference.
We can somewhat confirm this theory by performing few tests. Note how this and window seem to reference same object (if we can believe === operator), but Variable object (the one on which function is declared) is different from whatever this references.


    /* in Global code */
    function getBase(){ return this; }

    getBase() === this.getBase(); // false
    this.getBase() === this.getBase(); // true
    window.getBase() === this.getBase(); // true
    window.getBase() === getBase(); // false
  

Misconceptions

The beauty of understanding why things work the way they work can not be underestimated. I’ve seen few misconceptions on the web related to misunderstanding of delete operator. For example, there’s this answer on Stackoverflow (with surprisingly high rating), confidently explaining how “delete is supposed to be no-op when target isn’t an object property”. Now that we understand the core of delete behavior, it becomes pretty clear that this answer is rather inaccurate. delete doesn’t differentiate between variables and properties (in fact, for delete, those are all References) and really only cares about DontDelete attribute (and property existence).

It’s also interesting to see how misconceptions bounce off of each other, where in the very same thread someone first suggests to just delete variable (which won’t work unless it’s declared from within eval), and another person provides a wrong correction how it’s possible to delete variables in Global code but not in Function one.

Be careful with Javascript explanations on the web, and ideally, always seek to understand the core of the issue ;)

`delete` and host objects

An algorithm for delete is specified roughtly like this:

  1. If operand is not a reference, return true
  2. If object has no direct property with such name, return true (where, as we now know, object can be Activation object or Global object)
  3. If property exists but has DontDelete, return false
  4. Otherwise, remove property and return true

However, behavior of delete operator with host objects can be rather unpredictable. And there’s actually nothing wrong with that: host objects are allowed (by specification) to implement any kind of behavior for operations such as read (internal [[Get]] method), write (internal [[Put]] method) or delete (internal [[Delete]] method), among few others. This allowance for custom [[Delete]] behavior is what makes host objects so chaotic.

We’ve already seen some IE oddities, where deleting certain objects (which are apparently implemented as host objects) throws errors. Some versions of Firefox throw when trying to delete window.location. You can’t trust return values of delete either, when it comes to host objects; take a look at what happens in Firefox:


    /* "alert" is a direct property of `window` (if we were to believe `hasOwnProperty`) */
    window.hasOwnProperty('alert'); // true

    delete window.alert; // true
    typeof window.alert; // "function"
  

Deleting window.alert returns true, even though there’s nothing about this property that should lead to such result. It resolves to a reference (so can’t return true on the first step). It’s a direct property of a window object (so can’t return true on a second step). The only way delete could return true is after reaching step 4 and actually deleting a property. Yet, property is never deleted.

The moral of the story is to never trust host objects.

ES5 strict mode

So what does strict mode of ECMAScript 5th edition bring to the table? Few restrictions are being introduced. SyntaxError is now thrown when expression in delete operator is a direct reference to a variable, function argument or function identifier. In addition, if property has internal [[Configurable]] == false, a TypeError is thrown:


  (function(foo){

    "use strict"; // enable strict mode within this function

    var bar;
    function baz(){}

    delete foo; // SyntaxError (when deleting argument)
    delete bar; // SyntaxError (when deleting variable)
    delete baz; // SyntaxError (when deleting variable created with function declaration)

    /* `length` of function instances has { [[Configurable]] : false } */

    delete (function(){}).length; // TypeError

  })();
  

In addition, deleting undeclared variable (or in other words, unresolved Referece) throws SyntaxError as well:


    "use strict";
    delete i_dont_exist; // SyntaxError
  

This is somewhat similar to the way undeclared assignment in strict mode behaves (except that ReferenceError is thrown instead of a SyntaxError):


    "use strict";
    i_dont_exist = 1; // ReferenceError
  

As you now understand, all these restrictions somewhat make sense, given how much confusion deleting variables, function declarations and arguments causes. Instead of silently ignoring deletion, strict mode takes more agressive and descriptive measures.

Summary

This post turned out to be quite lengthy, so I’m not going to talk about things like removing array items with delete and what the implications of it are. You can always refer to MDC article for that particular explanation (or read specs and experiment yourself).

Here’s a short summary of how deletion works in Javascript:

  • Variables and function declarations are properties of either Activation or Global objects.
  • Properties have attributes, one of which — DontDelete — is responsible for whether a property can be deleted.
  • Variable and function declarations in Global and Function code always create properties with DontDelete.
  • Function arguments are also properties of Activation object and are created with DontDelete.
  • Variable and function declarations in Eval code always create properties without DontDelete.
  • New properties are always created with empty attributes (and so without DontDelete).
  • Host objects are allowed to react to deletion however they want.

If you’d like to get more familiar with things described here, please refer to ECMA-262 3rd edition specification.

I hope you enjoyed this overview and learned something new. Any questions, suggestions and corrections are as always welcomed.

Categories: delete operator, DontDelete, ECMA-262, review, strict-mode, [[Delete]]

Comments (72)

  1. Gravatar

    qFox said on Jan 11, 2010 @ 10:08

    Nice (but lengthy ;) article. Seems to be correct though. Nice catch of the firebug issue.

    I remember IE is implementing the global object differently under the hood. Something about window != this in the global scope or something. I should test this when I have the time.

  2. Gravatar

    Rob Wright said on Jan 11, 2010 @ 10:28

    Very interesting article, thanks for taking the time to give your insights. Just the kind of thing I need to improve my JS knowledge.

  3. Gravatar

    Ryan Szulczewski said on Jan 11, 2010 @ 10:49

    Great article. The only thing that would have been more helpful if it would have explained when delete is useful (e.g. stopping memory leaks, performance, etc.)

  4. Gravatar

    David Semeria said on Jan 11, 2010 @ 11:16

    Juriy, what an excellent post!

    I really appreciate the time you put into this, and found it very informative.

    Thanks!

  5. Gravatar

    Asen Bozhilov said on Jan 11, 2010 @ 11:41

    Excellent article. When i read sentence after sentence i expect explanations of the things in my head and you make a sense about them.

    Only one mistake. In Spidermonkey global object has Prototype Chain. See code below:

    window.alert(this.__proto__); //[xpconnect wrapped native prototype]
    window.alert(this.__proto__.__proto__); //[object Global Scope Polluter]
    window.alert(this.__proto__.__proto__.__proto__); //[object Object]
    window.alert(this.__proto__.__proto__.__proto__ === Object.prototype); //true
    

    `hasOwnProperty` and `propertyIsEnumerable` lookups in Prototype chain for Global Object.

    Object.prototype.x = 10;
    window.alert(window.hasOwnProperty('x')); //true
    window.alert(window.propertyIsEnumerable('x')); //true
    

    The interesting part here is, Global Object inherit `hasOwnProperty` and `propertyIsEnumerable` from Object.prototype.

    window.alert(window.hasOwnProperty === Object.prototype.hasOwnProperty); //true
    window.alert(window.propertyIsEnumerable === Object.prototype.propertyIsEnumerable); //true
    

    `alert` prototype is defined in Global Object[[Prototype]]. Your example should be change to:

    window.alert(window.__proto__.__proto__.hasOwnProperty('alert')); //false
    window.alert(window.__proto__.hasOwnProperty('alert')); //true
    window.alert(delete window.__proto__.alert); //true
    
    window.alert('test'); //display test
    

    Regards for excellent article ;~)

  6. Gravatar

    Asen Bozhilov said on Jan 11, 2010 @ 13:13

    Regarding my previous post. Global Object and Global Object[[Prototype]] in Spidermonkey have owns internal [[GetOwnProperty]] method.
    Regarding:

    window.__proto__;

    This object has own [[Get]].

    window.__proto__.alert = false;
    console.log(typeof window.alert); //boolean
    console.log(delete window.__proto__.alert); //true
    console.log(typeof window.alert); //function
    

    Seems like lookup in prototype chain. But the next object in prototype chain doesn’t have property `alert`. So i think, `window.__proto__` has own implementation of [[Get]] method.

  7. Gravatar

    M said on Jan 11, 2010 @ 14:27

    @Juriy:

    Did you read more of the book? If so, would you recommend it (or were there other errors you noticed)?

  8. Gravatar

    zorg said on Jan 11, 2010 @ 19:58

    I ‘d be interested to know more about the difference between function declarations and function expressions

  9. Gravatar

    Ken Snyder said on Jan 11, 2010 @ 20:51

    Thanks for sharing your research! Very helpful.

  10. Gravatar

    Raphael Speyer said on Jan 12, 2010 @ 5:40

    Good post!

    However, the behaviour that you describe with “Not only does function declaration replaces previous value of a property, it also replaces that property attributes” is true for ES3 but not ES5.

    In the ES5 spec (10.5 steps 5d and 5e), if there is already a binding for ‘x’, CreateMutableBinding will not be called again but SetMutableBinding will, so the property value will be changed but not whether it is deletable. This means that tests 23 and 24 in your suite will always fail for ES5.

    I guess those tests are failing in most modern browsers because implementers are moving their ES3 engines to ES5.

  11. Gravatar

    Jordan said on Jan 12, 2010 @ 8:44

    Great explanation. The length – while daunting – really is necessary if you are to understand delete at the level that you need in order to debunk the book’s usage. I do agree with Ryan above, however, in that it would be nice to see some proper usage of delete (to control memory leaks mostly in my experience).

    And to echo “M”‘s sentiment above… did you read more of the book? Were there many other inaccuracies?

  12. Gravatar

    Pari Nannapaneni said on Jan 12, 2010 @ 14:58

    Great post !

    I was just declaring ‘window.variablename = .. ‘ for any variables that i wanted
    to delete later ( to store some temporary JSON result or something)

    After reading this post now i am now a lot more comfortable using the ‘delete’

    thanks for explaining.

  13. Gravatar

    Grigory Kruglov said on Jan 12, 2010 @ 16:29

    Nice article!

    One note though, which you might find interesting, regarding this statement:
    Unfortunately, this kind of spoofing doesn’t work in any implementation I tried. I might be missing something here, or this behavior might simply be too obscure for implementors to pay attention to.

    It is implemented properly in the BlackBerry browser :-) Just ran the test on my Bold 9700 to double check, and surely enough I see all 24 green PASSes.

  14. Gravatar

    kangax (article author) said on Jan 13, 2010 @ 10:37

    @Ryan Szulczewski, @Jordan

    You’re right. I should have explained when to use delete, before delving into all the details on how it works. The point of this overview was mainly to emphasize that deleting variables is useless (unless those are declared within eval, which is very unlikely), and even not very future-compatible (due to ES5 strict mode behavior). Deleting properties of native, user-defined objects is perfectly fine, and there are certainly valid use cases for that.

    In Prototype.js, there’s an Element method which is an abstraction for DOM element creation. This method accepts object as a second argument, iterates over it and maps name/value of object properties to element attributes. Now, in some environments, setAttribute is faulty and can not set “name” attribute on element after its creation. Instead, that environment supports extended element creation syntax — document.createElement('<a name="foo">'). To work around that, when this deficiency is detected, we remove “name” property from an object and use this extended syntax. We then iterate over the remaining properties, operating on each one of them as we normally would. A perfectly valid use case for delete.

    When using object as a hash table, one might need to delete certain property, so that iterating over an object, or using in operator (or Object.prototype.hasOwnProperty) would properly report property as being non-existent. Note that simply assigning null or even undefined does not actually delete a property. It is still visible when iterating with for-in or using one of the above mentioned ways of inspection.

    Speaking of memory leaks, breaking circular references — the cause of the leaks — is usually done with simple null assignment. There’s usually no need to use delete. Moreover, null‘ing allows to “dereference” variables — what delete would normally not be able to do.

    var el = document.getElementById('foo');
    
    // circular reference is formed
    el.onclick = function() { /* ... */ };
    
    // circular reference is broken
    el = null;
    
    // can't `delete el` in this case, as `el` has DontDelete
    

    For these reasons, it’s best to stick with null‘ing when breaking circular references.

  15. Gravatar

    kangax (article author) said on Jan 13, 2010 @ 10:50

    Thanks everyone! I’m glad you enjoyed it.

    @zorg
    You can read about differences between function expressions and function declarations in my NFE article.

    @Grigory Kruglov
    Woah, I did not expect that. Thanks for this discovery! Just checked emulators of Blackberry 9530 (Storm), 9000 (Bold), 8320 (Curve), and 8100 (Pearl), and they all pass test suite fully, including last 2 assertions. Very surprising.

    @Raphael Speyer
    Ah, that’s interesting. Thanks for bringing it up. However, I don’t think current browser failures with changing property attributes have to do with ES5. Even older browsers — going back 5-10 years ago — exhibit absolutely the same behavior. And as per Grigory Kruglov’s comment, we now know that Blackberry browsers are compliant in this regard.

  16. Gravatar

    kangax (article author) said on Jan 13, 2010 @ 11:24

    @M, @Jordan

    Unfortunately, I only read through chapter on functions. The book feels beginner-oriented, so this is who I would recommend it for. I also haven’t really noticed author touching advanced topics or explaining things deeply. I don’t think there’s much in it for advanced users, but then I haven’t seen other chapters.

    Some of the mistakes I noticed (besides this whole delete misunderstanding) were:

    - Saying that function f(){} and var f = function(){} are “exactly the same”. That’s not really true.
    - Saying that “A drawback, of course, is that you cannot execute the same function twice”, when talking about anonymous self executing function. Not true, since we have arguments.callee.
    - Various minor nitpicks, like not using proper terminology: calling function expression “function literal” or global scope — “global namespace”. Not a big deal, of course, but I like when authors stick to standard terms (to avoid ambiguity and confusion).
    - Not mentioning Function constructor as a third way to create a function.

  17. Gravatar

    Dmitry A. Soshnikov said on Jan 14, 2010 @ 12:33

    Hi, kangax.

    Good article, thanks.

    Some additions bellow:

    Safari 2.x and 3.0.4 have problems with deleting function arguments; those properties seem to be created without DontDelete, so it is possible to delete them

    Although this bug has been fixed in newer versions of Safari, Chrome which is also based on WebKit still has such bug – there’s no {DontDelete} for arguments (v. 3.0.195.38, WinXP):

    function test(a, b) {
      alert([typeof a, typeof b]); // number, number
    
      delete a;
      delete arguments[1];
    
      // undefined, undefined - in Chrome
      // number, number - in other
      alert([typeof a, typeof b]);
    }
    
    test(1, 2);

    Also, it will be useful to know, that Opera (at least v.10.10 WinXP) doesn’t set {DontDelete} for catch clause’s parameter (12.14, ES-3):

    try {
      throw 'error';
    } catch (e) {
    
      alert(typeof e); // string
    
      delete e;
    
      // undefined - in current Opera
      // string - in other
      alert(typeof e);
    }

    I wrote about this in c.l.js: http://groups.google.ru/group/comp.lang.javascript/msg/a18b00bc8be5d542?hl=en

    It’s as if variable declarations in Global code do not create properties on Global object in IE

    The situation with variable declaration and the global object and the window host object in IE is more interesting than seems at first sight ;)

    Having e.g. such data in IE:

    a = 10;
    this.b = 20;
    window.c = 30;
    var d = 40;

    and using internal debugger of IE8 we can suppose such structure of the variable object for the global code:

    VO = {
      window: {
        b: - ?,
        c: - ? - should be there
      },
      d: on entering - undefined, then - 40,
      a: 10 - created on execution
    };

    This also can be seen in example of “redefining” and deleting variable with the same name as some host property’s name, e.g. “navigator”:

    alert(navigator); // [object], OK
    alert(navigator.userAgent); // exactly that object we expect
    
    // now use variable declaration
    // using [eval] which should not
    // set {DontDelete}
    
    eval('var navigator;');
    alert(navigator); // undefined, OK
    
    // set new value
    navigator = 10;
    alert(navigator); // 10, OK
    
    // remove it from the base object
    // as navigator has no {DontDelete}
    delete navigator;
    
    alert(navigator); // [object], ;)
    
    // and exactly restored main
    // [navigator] host object
    alert(navigator.userAgent);

    And if we again see into debugger, will see the following picture:

    VO = {
      window: {
        ...
        navigator:
        ...
      },
      navigator: 10
    };

    Here’s my more detailed explanation: http://groups.google.ru/group/comp.lang.javascript/msg/c1572441853282c6?hl=en

    Stoyan Stefanov’s Object-Oriented Javascript.

    This book has much inaccurate information, especially in chapter about objects and prototypes.

    /ds

  18. Gravatar

    Stoyan said on Jan 15, 2010 @ 14:49

    Thanks very much, kangax, this is an excellent writeup! Looks like a second edition of the book would be highly desirable :)

  19. Gravatar

    Sylvester Hesp said on Feb 9, 2010 @ 10:34

    About function declarations are instantiated after variable declarations
    Are you sure about this? Because I think you have misinterpreted something here. Functiondefinitions do not overwrite variable definitions. The reason

    function x() { }
    var x;
    typeof x; // "function"

    works is because the variabel declaration does not actually declare a new variable, because a variable with the name “x” (the function) already exists. However, should you initialize the variable, like so:

    function x() { }
    var x = 1;
    typeof x; // "number"

    x actually becomes a number, because the reference to the function is overwritten.

    As far as I understand it, all functions in the current scope are declared before anything else. That’s why this outputs 2 rather than 1:

    function x() { return 1; }
    alert(x());
    function x() { return 2; }

    Of course, an eval() will overwrite a variable with the function definition because it’s only executed at the call site of eval() – it is not parsed with the rest of normal code.

    Note that this is based on actual implementations, I haven’t taken the time to actually read the standard about this so maybe all implementations and myself are wrong :)

  20. Gravatar

    Java developer said on Feb 18, 2010 @ 16:21

    Very nice article!

  21. Gravatar

    niaher said on Feb 21, 2010 @ 11:37

    Awesomeness! There should be more of such in-depth articles on the Internet. The drag-and-drop mentality will never be able to compete with this quality.

  22. Gravatar

    tot2ivn said on Feb 28, 2010 @ 11:21

    Thanks for such a great in-depth article..!

  23. Gravatar

    Marcel Duran said on Mar 31, 2010 @ 15:06

    Nice post kangax, very informative. I noticed that weird firebug delete behavior before then I ran the following commands:

    To see what’s been used to run firebug console:

    console.log(arguments.callee.toString())
    function (expr) {
        try {
            var result = window.eval(expr);
            if (typeof result != "undefined") {
                window.console.notifyFirebug([result], "evaluated", "firebugAppendConsole");
            }
        } catch (exc) {
            var result = exc;
            result.source = expr;
            window.console.notifyFirebug([result], "evaluateError", "firebugAppendConsole");
        }
    }

    In fact it’s using eval as you suspected.

    To see what is really been passed as argument to that function:

    console.log(arguments[0])
    with(_FirebugCommandLine){console.log(arguments[0])};

    It’s using with statement adding an extra lookup to the scope chain, so besides the eval code it also has its own scope for the code executed within it.

    console.log(this === _FirebugCommandLine) // true 

    I have a performance related question. According to Steve SoudersEven Faster Websites book, on chapter 2 (page 19) the authors (Ajaxian founders) suggest to simultaneously remove a node from the DOM and delete it like:

    delete nodeToDelete.parent.removeChild(nodeToDelete)

    They claim it gives a hint to the garbage collector to remove this unused element from memory. I’m not sure if it really does, I know JSLint complains about such line. Do you have any thoughts on this?

  24. Gravatar

    kangax (article author) said on Apr 4, 2010 @ 9:02

    @Marcel Duran

    I find it hard to believe that delete nodeToDelete.parent.removeChild(nodeToDelete) (I suppose parent instead of parentNode is a typo?) gives a hint to garbage collector to remove element from memory. First of all, I’m not aware of any explicit hinting patterns except for global CollectGarbage method in JScript.

    Second, if we look closer at this expression, we’ll see that it’s really equivalent to delete nodeToDelete. This is because function call operator has higher precedence than delete operator, so nodeToDelete.parentNode.removeChild(nodeToDelete) expression is executed first, evaluates to nodeToDelete (since this is what removeChild is defined to return), and is than passed to delete operator. So what we really have here is delete nodeToDelete.

    Now, what happens next depends on how nodeToDelete is declared. If it’s a local variable (most likely), it should be a property of ActivationObject and have [[DontDelete]] set on, in which case delete nodeToDelete would essentially be a noop. The situation would be different if nodeToDelete was declared from within eval (or be part of an object injected into a scope via with statement, and not have [[DontDelete]]). Since both of latter cases are unlikely, this pattern mostly looks like a bogus ;)

  25. Gravatar

    denisdeng said on Apr 11, 2010 @ 3:51

    good article! I have learned a lot from this. thank you! so I have translate  into Chinese:
    http://www.denisdeng.com/?p=858

  26. Gravatar

    bledi said on Jun 18, 2010 @ 5:14

    this article is a MUST read!

  27. Gravatar

    Ray said on Jun 30, 2010 @ 1:56

    With all the inaccuracies mentioned above, will purchasing and learning from the book mess up my JS knowledge? I’ve read DOM Scripting and Bulletproof Ajax and wanted something to take me further and this book by Stoyan seems like a good choice. What’s your take?

  28. Gravatar

    Joss said on Oct 23, 2010 @ 8:19

    Really excellent article, very insightful and have never considered this.

    Keep up the good work!

    Joss

  29. Gravatar

    Rohit said on Dec 30, 2010 @ 23:20

    Very interesting post. One doesn’t usually find material describing the idiosyncrasies of Javascript implementation to such detail.
    I was about to post a doubt regarding use of delete on a sequential array & its implications on array length – Something I had encountered while working on Node.js.
    No need now that I have read abt array length in your newer post ‘How ECMAScript 5 still does not allow to subclass an array’.
    Thanks for both these enlightening posts :-) .

  30. Gravatar

    Yuval said on Jan 28, 2011 @ 12:36

    This is the best article I’ve read about Javascript variable scope. Thanks!

  31. Gravatar

    Lupons said on Feb 21, 2011 @ 11:44

    Excellent article. It is a bit lengthly but neccesary to understand what it needs to explain. Excellent work!

  32. Gravatar

    Lars Gunther said on Mar 16, 2011 @ 6:12

    A quick test shows that the JavaScript console is a better choice than Firebug for testing. Had Stoyan done that perhaps the book would have had accurate information.

    I use the console when teaching and this reinforces my resolve to keep doing that.

  33. Gravatar

    Pablo Benito said on Apr 16, 2011 @ 7:34

    Hi,
    It is a very interesting post!,

    I have a question about the section “Gecko DontDelete bug”
    You tell us that this.foo = 1 should not change the current Variable Object property defined previusly as a function. Then implicitly you are telling us that we can access current Variable Object properties acceding “this” properties. Why? Which is the actual relation within the current Variable Object and “this”.

    My example code :
    function X(a){
    console.log(a);//currentVariableObject.a this return 666
    console.log(this.a); //this return undefined
    }

    var x = new X(666);

    Another Question :
    In a browser, under global scope, it seems that we can access the real Variable Object (Global Object in this case) under the name window (I think that the virtual machine don’t give as acces to de Variable objects, only to copies in accessible objects like window or the referened by this). in a function context how can we direct access the Activation Object for discriminate between ActiveObject.a and this.a in my example above?

    Your example code:

    function foo(){}
    delete foo; // false (as expected)
    typeof foo; // “function” (as expected)

    /* now assign to a property explicitly */

    this.foo = 1; // erroneously clears DontDelete attribute
    delete foo; // true
    typeof foo; // “undefined”

    /* note that this doesn’t happen when assigning property implicitly */

    function bar(){}
    bar = 1;
    delete bar; // false
    typeof bar; // “number” (although assignment replaced property)

  34. Gravatar

    André said on Jun 22, 2011 @ 9:31

    With that undefined thing lingering around, it is hard to imagine how it would be if it didn’t work the way you described.

    function() {
    delete blah;
    some_func(blah); // undefined or not?
    var blah;
    }

  35. Gravatar

    Shay Ben Moshe said on Oct 17, 2011 @ 16:18

    Excellent article.
    I have learned a lot from it, thank you!

  36. Gravatar

    Timothy Kay said on Dec 14, 2011 @ 10:17

    Your punchline is confusing:

    “Well, as I said before, Eval code has a special behavior when it comes to variable declaration. Variables declared within Eval code are actually created as properties without DontDelete.”

    The first time I read it, I parsed it this way, with the parsing shown using parentheses:

    “Well, as I said before, (Eval code has a special behavior when it comes to variable declaration. Variables declared within Eval code are actually created as properties without DontDelete).”

    I thought to myself, on the contrary, he didn’t say before that Eval code creates properties without DontDelete. It left me confused.

    What you meant to convey is this:

    “Well, (as I said before, Eval code has a special behavior when it comes to variable declaration). Variables declared within Eval code are actually created as properties without DontDelete.”

    You can make that clarification by adding a transition and some emphasis:

    “Well, as I said before, Eval code has a special behavior when it comes to variable declaration. But here’s the thing: Variables declared within Eval code are created as properties without DontDelete.

  37. Gravatar

    Sriram Krishnan said on Jan 20, 2012 @ 18:40

    Awesome Article ! kudos.

    var x = 1;

    /* Can’t delete, `x` has DontDelete */

    delete x; // false
    typeof x; // “number”

    eval(‘function x(){}’);

    /* `x` property now references function, and should have no DontDelete */

    In here the Eval is doing what is comparable to reassiging x (like x=2), so its attributes are not affected by that eval ! this is my understanding correct me if i am wrong

  38. Gravatar

    Troy III said on Feb 14, 2012 @ 11:53

    cite: Firefox throw when trying to delete window.location. You can’t trust return values of delete either, when it comes to host objects; take a look at what happens in Firefox:
    /* “alert” is a direct property of `window` (if we were to believe `hasOwnProperty`) */
    window.hasOwnProperty(‘alert’); // true
    delete window.alert; // true
    typeof window.alert; // “function”

    -perhaps it’s a matter of FX version but: [attention] It is also possible that the >>document type<< of the page loaded on the current window has modified the behavior of the code being fed to console.
    My recent check shows that:
    On chrome ; latest firefox & IE9,
    window.hasOwnProperty('alert'); // (is) false, and correct.

    Safari however is returning true [which is incorrect], including Opera [which is correct].

    Safari’s return of “true” -is not true at all. In Safari the “alert” function is not a property of “window” either.
    That’s why deleting alert on window will yield true as it does for any other nonexistent window property- because it’s not there…
    Which means: Safari has a wrong implementation of hasOwnPrperty.
    So does Opera but in this case Opera speaks the truth and lat’s see why?

    The “alert” function in Opera is a property of “window” for a fact, and
    delete alert // true
    Is speaking the truth, since the
    alert //call will rise an >> error : 'undefined variable'
    Which means that the action is destructive and that the “alert” function will not be available for the rest of that session. Meaning that, in Opera you can delete the alert function since it is indeed a property of the actual window object. But that’s not the case with others.

    sumarum
    In all other mentioned browsers the “alert” function on “window object” is a property of window prototype, not the window itself. Therefore window.hasOwnProperty('alert') should return false in Safari too.

  39. Gravatar

    Jeff said on Feb 26, 2012 @ 15:15

    Waaay too long.

  40. Gravatar

    lb said on Mar 8, 2012 @ 17:46

    You do know this is one of my most favourite bookmarks on the internet, though I heard you’re on MS’s payroll now?

    What’s your view on DOJO’s AMD and declare API’s?

  41. Gravatar

    Tamil Selvan said on Mar 13, 2012 @ 10:25

    (function(){ var x = 1; delete x; assertTrue(typeof x != ‘number’) })(); PASS ??
    How come this test passed?

  42. Gravatar

    Sriram Krishnan said on Mar 13, 2012 @ 10:55

    @Tamil Selvan

    try this , it returns number

    (function(){ var x = 1; delete x; alert(typeof x) })();

  43. Gravatar

    Tamil Selvan said on Mar 14, 2012 @ 0:18

    @Sriram Krishnan Ya it is true typeof x should be number but how come assertTrue(typeof x != ‘number’) Passed?
    I visited that test page mentioned in the tutorial from my Chrome browser. I have just pasted the output of the test.

  44. Gravatar

    Mike said on May 3, 2012 @ 4:36

    Wow, one of the most important pieces of js literature I’ve ever read. Thanks.

  45. Gravatar

    linus脱袜子 said on May 15, 2012 @ 4:13

    Through reading ‘The definitive guide of JavaScript’, I konw that JavaScript variables have a few attributes which may be involved with the delete operation, which are enumerable, configurable and writable, I haven’t see anything attribute named dontdelete, so, I wonder whether you just make this name up or is there any authortive references? More than glad to hear your answer, and indeed, your article is very inspiring, I’ve experiment the codes in rhino javascript shell hosted on Ubuntu, you’re totally right. Thank you again for your article and explanation, looking forward to communicate with you. Best regards.

  46. Gravatar

    Animal said on May 16, 2012 @ 14:57

    Linus, from the ECMA standard:

    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.

Trackbacks

  1. Webdev Weekly #1 | samuli.hakoniemi.net said:

    [...] Understanding delete [...]

  2. Interesting Finds: 2010 01.10 ~ 01.18 - gOODiDEA.NET said:

    [...] Understanding delete [...]

  3. Perfection kills » Javascript quiz said:

    [...] else does it before me. Meanwhile, you can take a look at my articles on function expressions and delete operator, understanding which would help you answer some of these questions, and more importantly, explain [...]

  4. Weekly Digest for February 11th – BorkWeb said:

    [...] Perfection kills » Understanding delete — 3:42pm via [...]

  5. links for 2010-03-30 « Daniel Harrison's Personal Blog said:

    [...] Perfection kills » Understanding delete (tags: javascript) Possibly related posts: (automatically generated)links for 2009-10-07links for 2009-04-08links for 2010-03-10Keep to the Script   Leave a Comment [...]

  6. Publishing 5 books this year | Refresh said:

    [...] some excel­lent cri­tiques (of this oth­er­wise best­selling book!), such as this one by @kangax, which is the arti­cle that actu­ally prompted me to pitch a sec­ond edi­tion to the [...]

  7. 转:理解javascript中的delete机制(1)  -  JavaScript在线教程 said:

    [...] 在javascript中,我们有时候要使用delete删除对象。但是,对于delete的一些细节我们未必尽知。昨天,看到kangax分析delete的文章,获益匪浅。本文将文章的精华部分翻译出来,与各位分享。 [...]

  8. Variables vs. Properties in JavaScript « JavaScript, JavaScript said:

    [...] full details on delete as it applies to variables and properties check out this priceless article by kangax. He also explains why Firebug appears to let you delete a [...]

  9. Understanding Undefined and preventing ReferenceErrors « JavaScript, JavaScript said:

    [...] undefined Angus Croll: Variables vs. properties in JavaScript Juriy Zaytsev (“kangax”): Understanding Delete Dmitry A. Soshnikov: ECMA-262-3 in detail. Chapter 2. Variable object. ECMA-262 5th Edition [...]

  10. Perfection kills » Understanding delete « Data Warehouse in the Cloud said:

    [...] 22, 2010 CollectGarbage via perfectionkills.com Posted by dmoraschi Filed in Uncategorized Leave a Comment [...]

  11. Publishing 5 books this year | phpied.com said:

    [...] some excellent critiques (of this otherwise bestselling book!), such as this one by @kangax, which is the article that actually prompted me to pitch a second edition to the [...]

  12. Perfection kills » Global eval. What are the options? said:

    [...] side effect of executing code globally via eval is that function and variable declarations create deletable bindings (which is most likely an insignificant [...]

  13. The Top 150 Web Development Highlights from 2010 | Programming Blog said:

    [...] 90. Understanding Delete [...]

  14. The Top 150 Web Development Highlights from 2010 | Programming Blog said:

    [...] 90. Understanding Delete [...]

  15. JavaScript中delete操作符 | Wang Jun's Blog said:

    [...] 参考:http://xo-tobacoo.javaeye.com/blog/346644http://xiaolele.javaeye.com/blog/682242http://perfectionkills.com/understanding-delete/ [...]

  16. [번역] 자바스크립트에서 변수와 프로퍼티의 차이 | Inside jQuery said:

    [...] 변수와 프로퍼티에 어떻게 적용되는지 에 대한 자세한 설명은 http://perfectionkills.com/understanding-delete/을 [...]

  17. Cheatsheet: 2011 04.01 ~ 04.10 - gOODiDEA.NET said:

    [...] Understanding delete [...]

  18. JavaScript Delete Keyword Troubles « Eric Leads – JavaScript Architect said:

    [...] Read Understanding Delete on PerfectionKills.com   No Comments [...]

  19. Mozilla Hacks Weekly, September 15th 2011 ✩ Mozilla Hacks – the Web developer blog said:

    [...] Griffiths Understanding delete – Great article on delete in JS and ( at least in part ) on how developer tools can betray [...]

  20. Do you know the javascript “Delete” operator? « Fabio Stawinski said:

    [...] interesting and almost nobody uses it: http://perfectionkills.com/understanding-delete/ Compartilhe:Like this:LikeBe the first to like this [...]

  21. javascript里delete操作符什么时候能成功删除变量? - Leon's blog said:

    [...] 有时候却不掉成功删除的情况. 这篇Understanding delete牛文详细解释了, 为什么会这样, 什么样的变量能成功delete, [...]

  22. Perfection kills » Understanding delete | Maanas Royy said:

    [...] Perfection kills » Understanding delete. Share this:TwitterFacebookDiggLike this:LikeBe the first to like this post. This entry was posted in Uncategorized by m4manas. Bookmark the permalink. [...]

Leave a Comment

Please, don't forget to escape your input (<, > and &). Wrap code sections with <pre>

Allowed tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>