Почему глобальные переменные считаются плохой практикой?
Я продолжаю видеть предупреждения не использовать глобальные переменные в JavaScript, но кажется, что единственная причина, по которой люди говорят, что это засоряет глобальное пространство имен. Я могу представить, что это легко исправить, поместив все переменные в один большой объект. Теперь вопрос: есть ли другие причины не использовать глобальные переменные, кроме удобства? Есть ли проблемы с производительностью или совместимостью, связанные с ними?
9 ответов
Они загромождают глобальное пространство имен и работают медленнее, чем локальные переменные.
Прежде всего, иметь много глобальных переменных всегда плохо, потому что легко забыть, что вы объявили переменную где-то и случайно объявили ее где-то еще. Если ваша первая переменная была локальной, то у вас нет проблем. Если оно было глобальным, то оно просто перезаписывалось. Это становится еще хуже, когда вы попадаете в подразумеваемые глобалы (например, когда вы говорите someVar = someValue
без объявления someVar с var
ключевое слово).
Во-вторых, глобальные переменные "находят" для Javascript больше времени, чем для локальных. Разница в скорости не огромна, но она существует.
Для дальнейшего чтения и более глубокого объяснения того, почему глобальные списки считаются плохой практикой, вы можете проверить эту страницу.
Глобальные переменные могут значительно увеличить сцепление, значительно снижает масштабируемость и тестируемость вашего кода. Как только вы начнете использовать глобальные переменные, теперь вы должны знать, где и как изменяется переменная (т. Е. Нарушается инкапсуляция). Большая часть литературы и соглашений там будет утверждать, что производительность является наименьшей из ваших проблем при использовании глобальных.
Это фантастическая статья, объясняющая, почему глобальные переменные вызывают головные боли.
Короче говоря, глобальные переменные вызывают (и более) следующие проблемы.
1) Конфликты именования переменных - если вы работаете в команде, и вы и ваш коллега используете одно и то же имя переменной в глобальной области видимости, переменная, определенная последней, перезапишет исходную переменную. Это очевидное может иметь разрушительные последствия.
2) Безопасность. В частности, в Интернете каждый пользователь имеет доступ к объекту Window (или глобальному объекту). Помещая переменные в глобальную область видимости, вы даете любому пользователю возможность видеть или изменять ваши переменные.
3) Медленнее - это возможно незначительно, но оно все еще существует. То, как работает поиск переменных JavaScript, заключается в том, что механизм JavaScript будет выполнять поиск текущей области, в которой ищется переменная. Если он не может ее найти, он выполняет поиск следующей родительской области. Если он не найдет его там, он будет продолжать смотреть вверх, пока не достигнет глобального объекта, ищущего эту переменную. Если все ваши переменные находятся в глобальной области видимости, движок JavaScript всегда должен будет проходить через каждую область видимости, чтобы, наконец, достичь глобальной области видимости, чтобы найти переменную.
Если ваш сценарий очень длинный и вы используете эти переменные из множества функций, это увеличит ваше время отладки, поскольку значение глобальной переменной можно было изменить из любого места, поэтому, если вы отслеживаете, где это значение изменилось на непредвиденное значение, вы '' Я должен проверить их все.
Этот сценарий еще более болезненный, если разные программисты модифицируют эту переменную из других скриптов, включенных в вашу страницу.
Не должно быть никаких проблем с использованием глобальных переменных в вашем коде, если вы заключаете их в уникальную область имен / объект (чтобы избежать столкновения со сценариями, которые не являются вашими)
Есть одно преимущество использования глобальной переменной в javascript, и оно вытекает из того факта, что javascript не является сильным языком типов. поэтому, если вы передадите некоторые сложные объекты в качестве аргументов функции, вы, вероятно, потеряете всю интеллектуальность для этих объектов (внутри области действия функции), а вместо этого при использовании глобальных объектов сохраните эту интеллектуальность. и когда у вас есть интеллект, это на самом деле может улучшить время отладки (в отличие от того, что говорили другие...)
Я лично нахожу это очень полезным, и это, безусловно, имеет место в моем коде.
(конечно, всегда нужно правильно балансировать между локальными и глобальными переменными)
Чтобы добавить еще одну глобальную опасность в JavaScript с глобальными переменными, они могут в конечном итоге скрыть стандартные API.
По сути, потому что к ним можно получить доступ из любого скрипта на странице и потому что вы можете повторить его имя в той же области видимости. Вот почему многие движки Javascript используют этот код:
(function(){
var foo = 'foo',//Local
bar = 'bar';//Local
window.globalVar = foo + bar;//Global
})();
alert(foo);//Error
alert(bar);//Error
alert(globalVar );//'foobar'
В общем, мы должны сгруппировать похожий код и переменные вместе и возвести вокруг них заборы. Это называется классом, и это действительно помогает организовать программу. Хорошая организация облегчает другим чтение вашего кода, облегчает поддержку кода по мере роста программы, упрощает написание модульных тестов, упрощает повторное использование кода и позволяет избежать дублирования кода.
Все это необходимо при переходе от небольшой программы с одним сопровождающим к средней или большой программе, над которой работают несколько человек.
Глобалы не имеют ограждения вокруг себя и не группируются ни с каким другим кодом. Они потенциально могут влиять на любую другую часть программы, и с первого взгляда трудно понять, на какие части они влияют. Глобальные объекты нужно имитировать в модульных тестах, и на первый взгляд неясно, нужно ли их имитировать, просто глядя на определения методов.
Созданная вами глобальная переменная может перезаписать существующие свойства объекта окна. Потому что глобальные переменные обращаются в глобальном контексте, т.е. объекте окна.