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 omitting var
, when really, JS scales the function scopes, and if it makes it to the global scope without hitting that name, it appends a global property
with that data, rather than a global 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 to delete
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:
both terms represent the exact same set of global bindings.
...you're almost correct, but not quite. Property assignments like this.foo = 1
are saved into the global object. Variable declarations like var 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" refers to the global object. But global object is also acting as the
// variable object! Because of that, the following code works:
var foo = 1;
alert(this.foo); // 1
(function() {
// "this" still refers to the global object! But the *variable* object has
// changed because we're now in the execution context of a function, thus
// the behavior changes:
var bar = 2;
alert(this.foo); // 1
alert(this.bar); // undefined
})();
This doesn't mean that global properties and global variables are identical however. There are three hidden flags on all properties: ReadOnly
, DontEnum
, and DontDelete
.
When using implicit property declarations like this.foo = 1
, the DontDelete
attribute is set to false
. When you use variable declarations like var bar = 2
, the DontDelete
attribute is set to true
, thus representing the difference between them when you use the delete
operator.
In response to your rephrased question:
[T]he 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.
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 syntax var 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.