最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Are the terms "global property" and "global variable" synonyms? - Stack Overflo

programmeradmin1浏览0评论

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;:

  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.

  2. 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

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;:

  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.

  2. 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

Share Improve this question edited Jun 20, 2020 at 9:12 CommunityBot 11 silver badge asked Oct 2, 2012 at 15:00 Šime VidasŠime Vidas 186k65 gold badges288 silver badges391 bronze badges 7
  • What about implicit globals (foobar = 1, without var); are they equal to global properties or are they a third type? – Bergi Commented Oct 2, 2012 at 15:46
  • @Bergi -- like I said in my answer, JS will go through the chain of function-scopes until it finds that var/prop, and if it doesn't find it, it will append the value to a property of the global object. In your specific case, you just happen to already be starting within the global object, so there's less traversing for the engine to do. For a proof, try bob = "Bob"; delete bob; console.log(bob); // reference error - bob is not defined – LetterEh Commented Oct 2, 2012 at 15:53
  • @Bergi Implicit globals are just regular global properties. So, x = 1; is equivalent to window.x = 1; (in the browser). (Btw, strict mode throws on the first one.) – Šime Vidas Commented Oct 2, 2012 at 15:55
  • @Norguard: Thanks. I already did that, I only needed a confirmation :-) – Bergi Commented Oct 2, 2012 at 15:56
  • @Norguard "already starting with the global object" - What do you mean? You mean, since we're in global code, so there's no scope-traversal? – Šime Vidas Commented Oct 2, 2012 at 15:57
 |  Show 2 more ments

2 Answers 2

Reset to default 5

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.

发布评论

评论列表(0)

  1. 暂无评论