I have a global variable in Javascript (actually a window property, but I don't think it matters) which was already populated by a previous script but I don't want another script that will run later to see its value or that it was even defined.

I've put some_var = undefined and it works for the purpose of testing typeof some_var == "undefined" but I really do not think it's the right way to go about it.

Technical Explanation

1. Using var

In this case the reference g_a is created in what the ECMAScript spec calls "VariableEnvironment" that is attached to the current scope - this may be the a function execution context in the case of using var inside a function (though it may be get a little more complicated when you consider let) or in the case of "global" code the VariableEnvironment is attached to the global object (often window).

References in the VariableEnvironment are not normally deletable - the process detailed in ECMAScript 10.5 explains this in detail, but suffice it to say that unless your code is executed in an eval context (which most browser-based development consoles use), then variables declared with var cannot be deleted.

2. Without Using var

When trying to assign a value to a name without using the var keyword, Javascript tries to locate the named reference in what the ECMAScript spec calls "LexicalEnvironment", and the main difference is that LexicalEvironments are nested - that is a LexicalEnvironment has a parent (what the ECMAScript spec calls "outer environment reference") and when Javscript fails to locate the reference in a LexicalEenvironment, it looks in the parent LexicalEnvironment (as detailed in 10.3.1 and 10.2.2.1). The top level LexicalEnvironment is the "global environment", and that is bound to the global object in that its references are the global object's properties. So if you try to access a name that was not declared using a var keyword in the current scope or any outer scopes, Javascript will eventually fetch a property of the window object to serve as that reference. As we've learned before, properties on objects can be deleted.

Notes

It is important to remember that var declarations are "hoisted" - i.e. the are always considered to have happened in the beginning of the scope that they are in - though not the value initialization that may be done in a var statement - that is left where it is. So in the following code, a is a reference from the VariableEnvironment and not the window property and its value will be 10 at the end of the code:

function test() { a = 5; var a = 10; }

The above discussion is when "strict mode" is not enabled. Lookup rules are a bit different when using "strict mode" and lexical references that would have resolved to window properties without "strict mode" will raise "undeclared variable" errors under "strict mode". I didn't really understand where this is specified, but its how browsers behave.

What you said is a common misconception but is actually incorrect - in Javascript there are no "global variables". Variables defined without an explicit scope (such as using var outside a function) are properties of the "global object", which in web browsers is window. So - var a = 1; delete window.a; console.log(a); will successfully delete the variable and cause the last line to issue a reference error.
–
GussSep 20 '14 at 15:28

I am using Google Chrome v36. I tested on other browsers. It looks like it isn't consistent cross browsers. Chrome and Opera displayed 1, while Firefox, Safari and IE 11 on my computer gave an error.
–
DayongSep 22 '14 at 15:47

ECMA-262 v5.1 has this to say: "Every execution context has an associated VariableEnvironment. Variables and functions declared in ECMAScript code evaluated in an execution context are added as bindings in that VariableEnvironment’s Environment Record"; and also: "The global environment’s Environment Record is an object environment record whose binding object is the global object." So if after running my code example above, window.a == 1 then the browser is in violation of ECMA-262.
–
GussSep 23 '14 at 18:32

EDIT: My answer is somewhat inaccurate (see "Misconceptions" at the end). The link explains all the gory details, but the summary is that there can be big differences between browsers and depending on the object you are deleting from. delete object.someProp should generally be safe as long as object !== window. I still wouldn't use it to delete variables declared with var although you can under the right circumstances.

thanks @jedierikb for the link to that interesting article. more specifically to this part <perfectionkills.com/understanding-delete/#misconceptions&gt; of that article where the author states that noah's statement "delete is supposed to be a no-op" is rather inaccurate along with an excellent exlpanation why it is inaccurate. (Don't shoot the messenger!)
–
Rob WellsJul 9 '12 at 14:30

2

In regard to the last sentence of the revised answer, the only circumstance in which you can delete variables declared with var is when the variable was declared with eval.
–
Stephen BooherOct 5 '12 at 15:40

1

In this case, the delete statement doesn't appear to do anything at all. What's going on here?
–
Anderson GreenJun 10 '13 at 1:19

If you are implicitly declaring the variable without var, the proper way would be to use delete foo.

However after you delete it, if you try to use this in an operation such as addition a ReferenceError will be thrown because you can't add a string to an undeclared, undefined identifier. Example:

x = 5;
delete x
alert('foo' + x )
// ReferenceError: x is not defined

It may be safer in some situations to assign it to false, null, or undefined so it's declared and won't throw this type of error.

foo = false

Note that in ECMAScript null, false, undefined, 0, NaN, or '' would all evaluate to false. Just make sure you dont use the !== operator but instead != when type checking for booleans and you don't want identity checking (so null would == false and false == undefined).

Also note that delete doesn't "delete" references but just properties directly on the object, e.g.:

+1 for the complete explanation about the "delete behavior".
–
GmonCOct 20 '09 at 19:44

Thanks for the complete answer with all the details. I marked it up for this, but I've accepted Noah's answer because I believe that for a simple question brevity is more important then completion. Again - thanks for the great work you did on this answer.
–
GussOct 22 '09 at 14:55