Разве не правильно, что область действия и пространство имен - это две совершенно разные концепции?
Я бы не сказал, что области и пространства имен совершенно не связаны. Если мы возьмем буквальное значение « namespace », это будет пробел различных имен - уникальных и не конфликтующих с именами из других пробелов, как вы говорите.
Область определенно формирует пространство имен в этом отношении - имена переменных различны и не вступают в противоречие с именами из других областей. Однако область действия является внутренней и недоступна извне, поэтому она не особенно интересна для организации вещей.
Объект также образует пространство имен - имена свойств различны и не конфликтуют с именами других объектов. Вот почему объекты используются для структурирования кода в модули, и это традиционное значение «пространства имен» в JavaScript.
Правильно ли, что следующий литерал объекта создает новое пространство имен для bar
, избегая загрязнения глобального пространства имен (за исключением foo
), но bar
все еще находится в глобальной области видимости: var foo = { bar: 42 }
Нет, bar
не является членом глобальной области. Это свойство какого-то объекта.
Разве не правильно сказать "не создавайте глобальные переменные, чтобы не загрязнять глобальное пространство имен"? Глобальные и локальные переменные (область) отличаются от пространства имен.
Глобалы немного особенные в JS: они оба являются свойствами глобального объекта и переменными в глобальной области видимости. Вот почему мы говорим о «глобальном пространстве имен», чтобы охватить все - и особенно подчеркнуть, что имена не должны вступать в противоречие.
Если исключение загрязнения глобального пространства имен является единственной причиной, по которой мы не должны создавать глобальные переменные, разве недостаточно просто создавать новые пространства имен и при этом сохранять все это глобальным?
Создание пространств имен, например {bar: 42}
в приведенном выше примере, по-прежнему создает глобальные переменные: foo
. Он просто создает меньше переменных - по одной на модуль. Также это создает определенное соглашение об именах, а именно, что глобальные переменные должны ссылаться на модули, а не на обычные переменные. Мы не будем использовать var i, increment, decrement;
, но var counter = {i: …, increment(){…}, decrement(){…}};
, и будем ссылаться на их назначение в названии counter
.