Найти в Дзене
Герман Геншин

Программирование 101: Что такое глобальная переменная (и безопасна ли она?)

Глобальные переменные — тема для споров: это полезный инструмент или опасный пример неаккуратного кода? Давайте обсудим их функции, преимущества и причины, по которым стоит быть осторожным при их использовании. Компьютерная программа — это, по сути, набор инструкций, которые компьютер выполняет при запуске. Однако многие программы достаточно сложны, и они не укладываются в простую последовательность. Структуры, такие как блоки, функции и классы, помогают организовать код, делая его более управляемым. Функции — это основной инструмент группировки кода, который изолирует его поведение от остальной части программы. Вы можете вызывать функцию из разных частей кода и повторно использовать одну и ту же логику, избегая дублирования. Вот пример функции на JavaScript, использующей два типа переменных: аргумент функции и локальную переменную: Аргумент функции x автоматически заполняется значением, переданным функции при вызове. В данном примере он равен 4. Переменная i объявляется с помощью клю
Оглавление

Быстрые ссылки

Глобальные переменные — тема для споров: это полезный инструмент или опасный пример неаккуратного кода? Давайте обсудим их функции, преимущества и причины, по которым стоит быть осторожным при их использовании.

Что такое глобальная переменная?

Компьютерная программа — это, по сути, набор инструкций, которые компьютер выполняет при запуске. Однако многие программы достаточно сложны, и они не укладываются в простую последовательность. Структуры, такие как блоки, функции и классы, помогают организовать код, делая его более управляемым.

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

Вот пример функции на JavaScript, использующей два типа переменных: аргумент функции и локальную переменную:

Аргумент функции x автоматически заполняется значением, переданным функции при вызове. В данном примере он равен 4.

Переменная i объявляется с помощью ключевого слова let, что гарантирует её локальную область видимости. Изначально её значение не определено, до тех пор пока цикл for не присвоит и не изменит его значение.

Каждая переменная имеет свою область видимости внутри функции факториала; никакой другой код не может читать или изменять значения x или i. Вы можете запустить этот JavaScript в консоли браузера и убедиться, что переменные x и i недоступны вне функции:

-2

JavaScript также поддерживает глобальные переменные, которые действуют на протяжении всей программы. Вот альтернативная версия функции факториала, которая требует задать глобальную переменную перед вызовом вместо передачи аргумента:

Эта функция нарушает стандарты и на практике оказывается неэффективной; она показана лишь для демонстрации потенциального использования глобальных переменных. Она работает, но такое использование неудобно и громоздко. На самом деле, этот подход напомнит код на старом ассемблере, где концепция функций была почти отсутствующей.

Большинство языков программирования поддерживают глобальные переменные, но делают это по-разному. Например, PHP использует ключевое слово global для доступа к переменной, объявленной вне любой функции:

В приведенном коде функция inc использует ключевое слово global для получения доступа к переменной $a, объявленной на верхнем уровне. Когда она задает значение $a, это изменяет верхнюю переменную, что подтверждается выводом, равным 2. Однако $b не объявлена как глобальная внутри inc, поэтому функция изменяет только локальную переменную с тем же именем, сохраняя исходное значение верхней переменной равным 0.

Как можно неправильно использовать глобальные переменные?

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

Функция day_name() обращается к глобальному массиву для возвращения названия дня по его номеру. В небольшой программе это, вероятно, не станет проблемой, но по мере увеличения длины и сложности кода ошибки могут возникать чаще.

Поскольку переменная days является глобальной, любой другой участок кода может её изменить. Следующий код может быть добавлен в любое место и радикально изменить поведение day_name:

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

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

Кроме того, такой код становится сильно связанным, что затрудняет его тестирование. Наличие зависимости между функцией и глобальной переменной значит, что они всегда должны существовать вместе, что усложняет тестирование функции в изоляции.

Что такое модульное тестирование и почему оно важно?

Модульное тестирование — это процесс написания и автоматического запуска тестов, чтобы убедиться, что функции, которые вы написали, работают так, как задумано.

Чем больше глобальных переменных вы используете, тем выше вероятность конфликта имён. В JavaScript это особенно актуально из-за глобального объекта. В веб-браузере все глобальные переменные хранятся как свойства объекта Window. Это означает, что есть риск объявить глобальную переменную, которая переопределяет свойство Window, которое ваш код — или чей-то чужой — считает существующим.

Вызов window.alert() завершится ошибкой, так как теперь это строка, а не функция. Хотя вы не станете писать этот код намеренно, сделать это случайно очень легко. Чем больше глобальных переменных вы используете, тем выше вероятность конфликтов с другим кодом. Вы можете попытаться избежать этого, используя более необычные имена для глобальных переменных, но это всего лишь временное решение; нет никаких гарантий, что ваш код будет безопасным.

Все эти проблемы могут стать ещё более частыми, если вы используете внешние библиотеки в зависимости от того, как ваш язык защищает вас. JavaScript предлагает мало защиты, и если вы не будете осторожны, глобальные переменные могут сломать код библиотеки, которую вы используете — или наоборот.

И для чего же нужны глобальные переменные?

Тем не менее, глобальные переменные не всегда плохи — иногда они необходимы, и избегание их любой ценой может обойтись дорого! Вот разумный пример:

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

Важно отметить, что константа в JavaScript не является строго глобальной. Во-первых, она не будет добавлена как свойство объекта window. Но константа, объявленная на верхнем уровне скрипта, будет доступна всему коду, который идёт за ней.

Let, Var и Const: определение переменных в JavaScript

Завершение ES6 в 2015 году привнесло новые способы определения переменных в JavaScript.

Если вы всё же оказались в ситуации, когда используете глобальные переменные, вы можете снизить вероятность проблем, используя один глобальный объект. Например, вместо:

Вы можете хранить те же значения в глобальном объекте:

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

Наконец, документация — ваш союзник. Если вам нужно использовать глобальные переменные, убедитесь, что они задокументированы в комментариях, особенно если вы рассматривали альтернативный подход, но в итоге отклонили его. Имена переменных также служат документацией, поэтому убедитесь, что вы используете чёткие, лаконичные и информативные имена, которые объясняют назначение каждой переменной.

Если вам понравилась эта статья, подпишитесь, чтобы не пропустить еще много полезных статей!

Вы также можете читать наши материалы в:

Наука
7 млн интересуются