Являются ли термины "глобальная собственность" и "глобальная переменная" синонимами?

Глобальный объект служит лексической средой верхнего уровня (верхняя часть цепочки областей, если хотите). Это означает, что глобальные свойства могут быть доступны через прямые ссылки (например, переменные):

// global code
this.foo = 1;        // creating a global property
foo                  // accessing the global property via a direct reference

Это также означает, что глобальные переменные могут быть доступны через ссылки на свойства:

// global code
var foo = 1;         // creating a global variable
this.foo             // accessing the global variable via a property reference

ИНТЕРПРЕТАЦИЯ 1

Теперь, основываясь на приведенной выше информации, казалось бы, было бы целесообразно использовать термины "глобальная переменная" как "глобальное свойство" взаимозаменяемо, что означает, что оба термина представляют собой то же самое множество глобальных привязок.


Однако существуют две отличия между глобальной переменной, созданной с помощью var, например. var foo = 1; и глобальное свойство, созданное посредством назначения, например. this.foo = 1;:

  • Глобальные переменные статически ограничены, тогда как глобальные свойства динамически добавляются в глобальную среду:

    foo // => undefined
    bar // throws ReferenceError
    
    var foo = 1;
    this.bar = 1;
    

    Итак, глобальные переменные связаны перед оценкой программы, тогда как глобальные свойства привязаны во время оценки программы, когда вычисление присваивается.

  • Глобальные переменные не настраиваются, т.е. они не могут быть удалены (более конкретно, их соответствующие привязки не могут быть удалены из среды впоследствии), тогда как глобальные свойства, созданные посредством назначения, настраиваются.

    // 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
    

При этом следует отметить, что можно создавать неконфигурируемые глобальные свойства:

Object.defineProperty( this, 'bar', { value: 1 }); // non-configurable by default

ИНТЕРПРЕТАЦИЯ 2

Теперь, основываясь на этой новой информации, можно сказать, что глобальные привязки с глобальным глобальным значением могут быть названы глобальными связями только глобально, а динамически добавленные глобальные привязки - это просто глобальные свойства, но не глобальные переменные, что означает, что термин "глобальная переменная" представляет подмножество множества, представленного термином "глобальное свойство" , как в:

Все глобальные переменные являются глобальными свойствами
Только глобальные свойства с глобальным глобальным переменным


Итак, какая интерпретация верна? Оба термина представляют один и тот же набор привязок или один подмножество другого?


ВОПРОС

Я понимаю термин "глобальное свойство" - глобальное свойство является свойством глобального объекта. Однако термин "глобальная переменная" выглядит неоднозначным. Некоторые используют его как синоним "глобального свойства", а другие определяют его как глобальное свойство, которое было определено с помощью инструкции var. Цель моего вопроса - определить, какое из этих двух значений верно.

Ответ 1

Хорошо, вы уже знаете все, что я сказал бы, чтобы различать граничные переменные и свойства, которые привязаны к window.

Если вы хотите получить действительно, действительно педантичный, я полагаю, что вы могли бы рассматривать глобальную область как функциональную область, так и область, в которой объект window расширяется свойствами с использованием тех же скрытых параметров конфигурации, что и что предусмотрено в программе (например: vars можно переназначить, но не удалить). Таким образом, в том смысле, что касается функциональности, они различны и отражают атрибуты свойств и переменных во всем мире.

И ссылаться на них как таковую вполне нормально. Но большинство людей там даже не осознают разницу, не говоря уже о различии между этими двумя терминами.
Даже важные авторы JS ссылались на установку a global variable случайно, опуская var, когда действительно JS масштабирует области видимости функции, и если она попадает в глобальную область без удара этого имени, она добавляет global property с этими данными, а не с global variable.

Но это действительно приводит нас к сути - сильное и стабильное и надежное приложение JS, живущее на современной веб-странице вместе с другими приложениями, действительно не должно быть слишком обеспокоено различиями.
Цель состоит в том, чтобы использовать как можно меньше глобальных свойств и переменных в этом случае.

Кроме того, опасность столкновения переменных/свойств одинакова, независимо от того, что это такое.
Переменные невосприимчивы к delete, но каковы шансы какой-либо полезной программы на delete свойство, которое он никогда не установил?

Так что лично я думаю, что хорошо понимать краевые случаи, но я также думаю, что, хотя педант во мне хочет согласиться с тем, что есть разница, и они не котермины, прагматик во мне содрогается, чтобы думать о где люди активно используют глобальный охват в той мере, в какой это имеет для них большое значение.

Ответ 2

Хорошее объяснение можно найти здесь, но я сокращу его, чтобы ответить на ваш вопрос. Когда вы говорите:

оба термина представляют собой то же самое множество глобальных привязок.

... ты почти прав, но не совсем. Назначения свойств, такие как this.foo = 1, сохраняются в глобальном объекте. Объявления переменной, такие как var bar = 2, однако, сохраняются в переменной.

При выполнении под глобальной областью как глобальный объект, так и объект переменной представляются одним и тем же объектом - глобальным объектом (когда вы выполняете в браузере, это объект window).

Я упоминаю об этом, потому что одного объяснения недостаточно для объяснения поведения этой программы:

// "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

})();

Это не означает, что глобальные свойства и глобальные переменные одинаковы. На всех свойствах есть три скрытых флага: ReadOnly, DontEnum и DontDelete.

При использовании неявных объявлений свойств, таких как this.foo = 1, атрибут DontDelete имеет значение false. Когда вы используете объявления переменных, такие как var bar = 2, атрибут DontDelete имеет значение true, что представляет собой разницу между ними при использовании оператора delete.


В ответ на ваш перефразированный вопрос:

[T] he термин "глобальная переменная" представляется неоднозначным. Некоторые используют его как синоним "глобальной собственности", в то время как другие определяют его как глобальную свойство, которое было определено с помощью инструкции var. Цель моего вопрос заключается в том, чтобы определить, какое из этих двух значений верно.

Этот термин четко не определен, и поэтому вы просите не более, чем мнение.

В общем случае термин "глобальное свойство" используется при создании переменной с использованием синтаксиса this.foo = 1, а термин "глобальная переменная" используется при создании переменной с использованием синтаксиса var bar = 2. Больше нечего обсуждать.

Ни один из этих терминов не имеет никакого отношения к тому, что происходит за кулисами, поэтому лучшее, что вы можете сделать, это понять, что на самом деле происходит за кулисами, которые вы уже сделали.

Далее, требуя абсолютного определения на двух произвольных терминах, вы просто будете непопулярным человеком.