Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I unset a JavaScript variable?

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.

What do you think?

like image 841
Guss Avatar asked Oct 20 '09 19:10

Guss


People also ask

How do you unset a variable in typescript?

The correct way to "unset" is to simply set the variable to null .

How do you delete a declared variable?

Deleting a variable in JavaScript However, if your variable x first appeared in the script without a declaration, then you can use the delete operator ( delete x; ) and your variable will be deleted, very similar to deleting an element of an array or deleting a property of an object.

What is delete in JavaScript?

The JavaScript delete operator removes a property from an object; if no more references to the same property are held, it is eventually released automatically.


2 Answers

The delete operator removes a property from an object. It cannot remove a variable. So the answer to the question depends on how the global variable or property is defined.

(1) If it is created with var, it cannot be deleted.

For example:

var g_a = 1; //create with var, g_a is a variable delete g_a; //return false console.log(g_a); //g_a is still 1 

(2) If it is created without var, it can be deleted.

g_b = 1; //create without var, g_b is a property delete g_b; //return true console.log(g_b); //error, g_b is not defined 

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 LexicalEnvironments are nested - that is a LexicalEnvironment has a parent (what the ECMAScript spec calls "outer environment reference") and when JavaScript fails to locate the reference in a LexicalEnvironment, 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

  1. It is important to remember that var declarations are "hoisted" - i.e. they 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; } 
  2. 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.

like image 163
Dayong Avatar answered Sep 20 '22 14:09

Dayong


scunliffe's answer will work, but technically it ought to be

delete window.some_var; 

delete is supposed to be a no-op when the target isn't an object property. e.g.,

(function() {    var foo = 123;    delete foo; // wont do anything, foo is still 123    var bar = { foo: 123 };    delete bar.foo; // foo is gone }()); 

But since global variables are actually members of the window object, it works.

When prototype chains are involved, using delete gets more complex because it only removes the property from the target object, and not the prototype. e.g.,

function Foo() {} Foo.prototype = { bar: 123 }; var foo = new Foo(); // foo.bar is 123 foo.bar = 456; // foo.bar is now 456 delete foo.bar; // foo.bar is 123 again. 

So be careful.

Note: 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.

like image 27
noah Avatar answered Sep 18 '22 14:09

noah