The global object serves as the top-level lexical environment (the top of the scope-chain, if you will). This means that global properties may be accessed via direct references (like variables):
// global code
this.foo = 1; // creating a global property
foo // accessing the global property via a direct reference
This also means that global variables may be accessed via property references:
// global code
var foo = 1; // creating a global variable
this.foo // accessing the global variable via a property reference
INTERPRETATION 1
Now, based on the above information, it would seem that it would be appropriate to use the terms "global variable" an "global property" interchangeably, meaning that both terms represent the exact same set of global bindings.
However, there are two differences between a global variable created using var
,e.g. var foo = 1;
, and a global property created through an assignment, e.g. this.foo = 1;
:
Global variables are statically scoped, whereas global properties are dynamically added to the global environment:
foo // => undefined bar // throws ReferenceError var foo = 1; this.bar = 1;
So, global variables are bound before program evaluation, whereas global properties are bound during program evaluation, when the assignment is evaluated.
Global variables are non-configurable, i.e. they cannot be deleted (more specifically, their corresponding bindings cannot be removed from the environment subsequently), whereas global properties created through assignment are configurable.
// the names "foo" and "bar" are bound to the global environment var foo = 1; this.bar = 1; // the binding "bar" can be removed from the global environment subsequently delete this.bar; // the binding "foo" cannot be removed subsequently
That being said, it should be noted that it is possible to create non-configurable global properties:
Object.defineProperty( this, 'bar', { value: 1 }); // non-configurable by default
INTERPRETATION 2
Now, based on this new information, one could say that only statically scoped global bindings may be referred to as both global properties and global variables, whereas dynamically added global bindings are merely global properties, but not global variables, meaning that the term "global variable" represents a subset of the set represented by the term "global property", as in:
All global variables are global properties
Only statically scoped global properties are global variables
So, which interpretation is correct? Do both terms represent the same set of bindings, or is one a subset of the other?
THE QUESTION
I do understand the term "global property" - a global property is a property of the global object. However, the term "global variable" appears to be ambiguous. Some use it as a synonym for "global property", while others define it to mean a global property which has been defined via a var
statement. The intent of my question is to determine which of these two meanings is correct
Well, you already know everything I would have said to differentiate between the edge-cases of variables and properties which are attached to
window
.If you wanted to get really, really pedantic, I suppose that you could consider the global scope to be both a functional-scope and a scope in which the
window
object is extended with properties using the same hidden configuration settings as what is provided within the program (eg: vars can be reassigned but not deleted). So in that sense, as far as functionality is concerned, they are different, and reflect attributes of properties and variables, globally scoped.And referring to them as such is totally fine.
But the majority of people out there don't even recognize the difference, let alone differentiate between the two terms.
Even the important JS authors out there have referred to setting a
global variable
accidentally, by omittingvar
, when really, JS scales the function scopes, and if it makes it to the global scope without hitting that name, it appends aglobal property
with that data, rather than aglobal variable
.But that really sort of brings us to the crux -- a strong and stable and reliable JS application, living on a modern webpage along with other applications, really shouldn't be too concerned with the differences.
The goal is to use as few global properties and variables as possible, in that case.
Moreover, the danger of variable/property collision is the same, regardless of which it is.
Variables are immune to
delete
, but what are the chances that any useful program is going todelete
a property it's never even set?So personally, I think it's good to understand the edge-cases, but I also think that while the pedant in me wants to agree that there's a difference, and they are not coterminous, the pragmatist in me shudders to think of a world where people are actively using the global scope to the extent where this makes a large difference to them.
A good explanation can be found here, but I'll shorten it down to answer your question. When you say:
...you're almost correct, but not quite. Property assignments like
this.foo = 1
are saved into the global object. Variable declarations likevar bar = 2
however are saved into the variable object.When executing under global scope, both the global object and the variable object are represented by the same object--the global object (when you're executing in a browser, this is the
window
object).I mention this because your explanation alone is insufficient to explain the behavior of this program:
This doesn't mean that global properties and global variables are identical however. There are three hidden flags on all properties:
ReadOnly
,DontEnum
, andDontDelete
.When using implicit property declarations like
this.foo = 1
, theDontDelete
attribute is set tofalse
. When you use variable declarations likevar bar = 2
, theDontDelete
attribute is set totrue
, thus representing the difference between them when you use thedelete
operator.In response to your rephrased question:
The term is not clearly defined, and therefore you are asking for nothing more than an opinion.
In general, the term "global property" is used when you create a variable using the syntax
this.foo = 1
, and the term "global variable" is used when you create a variable using the syntaxvar bar = 2
. There's nothing more to discuss.Neither term has a true bearing on what goes on behind the scenes, thus the best you can do is understand what actually goes on behind the scenes, which you have already done.
Further demanding an absolute definition on two arbitrary terms will simply cause you to be an unpopular person.