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?
ECMAScript 2015 offers Reflect API. It is possible to delete object property with Reflect.deleteProperty():
To delete property of global
window
object:In some cases properties cannot be deleted (when the property is not configurable) and then this function returns
false
(as well as delete operator). In other cases returnstrue
:There is a difference between
deleteProperty
function anddelete
operator when run in strict mode:In addition to what everyone had written, also note that
delete
returns boolean. It can tell you if the delete was successful or not.UPDATE:
Testing on latest Chrome, everything was deleltable.
delete
function returnedtrue
for all of the following methods, and actually removed them:Variables, in contrast with simple properties, have attribute [[Configurable]], meaning impossibility to remove a variable via the delete operator. However there is one execution context on which this rule does not affect. It is the eval context: there [[Configurable]] attribute is not set for variables.
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:
(2) If it is created without
var
, it can be deleted.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 usingvar
inside a function (though it may be get a little more complicated when you considerlet
) or in the case of "global" code the VariableEnvironment is attached to the global object (oftenwindow
).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 withvar
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 avar
keyword in the current scope or any outer scopes, Javascript will eventually fetch a property of thewindow
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. 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 avar
statement - that is left where it is. So in the following code,a
is a reference from the VariableEnvironment and not thewindow
property and its value will be10
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.