Как сделать глобальную переменную в js
Оператор var объявляет переменную, инициализируя её, при необходимости.
Интерактивный пример
Синтаксис
var varname1 [= value1 [, varname2 [, varname3 . [, varnameN]]]];
Имя переменной. Может использоваться любой допустимый идентификатор.
Значение переменной. Любое допустимое выражение. По умолчанию значение undefined.
Описание
Объявление переменной всегда обрабатывается до выполнения кода, где бы она ни находилась. Область видимости переменной, объявленной через var , это её текущий контекст выполнения. Который может ограничиваться функцией или быть глобальным, для переменных, объявленных за пределами функции.
Присвоение значения необъявленной переменной подразумевает, что она будет создана как глобальная переменная (переменная становится свойством глобального объекта) после выполнения присваивания значения. Различия между объявленной и необъявленной переменными следующие:
1. Объявленные переменные ограничены контекстом выполнения, в котором они были объявлены. Необъявленные переменные всегда глобальны.
function x() y = 1; // возбудит ReferenceError в "строгом режиме" var z = 2; > x(); console.log(y); // выведет "1" console.log(z); // возбудит ReferenceError: z не определён вне x
2. Объявленные переменные инициализируются до выполнения любого кода. Необъявленные переменные не существуют до тех пор, пока к ним не выполнено присваивание.
.log(a); // Возбудит ReferenceError. console.log("still going. "); // Не выполнится.
var a; console.log(a); // Выведет "undefined" или "", в зависимости от браузера. console.log("still going. "); // Выведет "still going. ".
3. Объявленные переменные, независимо от контекста выполнения, являются ненастраиваемыми свойствами. Необъявленные переменные это настраиваемые свойства (т.е. их можно удалять).
var a = 1; b = 2; delete this.a; // Возбудит TypeError в "строгом режиме". В "нестрогом режиме" будет ошибка без уведомления. delete this.b; console.log(a, b); // Возбудит ReferenceError. // Свойство 'b' было удалено и больше не существует.
Из-за перечисленных различий, использование необъявленных переменных может привести к непредсказуемым последствиям. Рекомендовано всегда объявлять переменные, вне зависимости, находятся они внутри функции или в глобальном контексте. Присваивание значения необъявленной переменной в строгом режиме (en-US) ECMAScript 5 возбуждает ошибку.
Поднятие переменных
Объявление переменных (как и любые другие объявления) обрабатываются до выполнения кода. Где бы не находилось объявление, это равнозначно тому, что переменную объявили в самом начале кода. Это значит, что переменная становится доступной до того, как она объявлена. Такое поведение называется «поднятием» (в некоторых источниках «всплытием»).
= 2; var bla; // . // читается как: var bla; bla = 2;
Поэтому объявление переменных рекомендовано выносить в начало их области видимости (в начало глобального кода или в начало функции). Это даёт понять какие переменные принадлежат функции (т.е. являются локальными), а какие обрабатываются в цепи областей видимости (т.е. являются глобальными).
Важно отметить, что подъем будет влиять на объявление переменной, но не на инициализацию её значения. Значение присваивается при выполнении оператора присваивания:
function do_something() console.log(bar); // выведет undefined var bar = 111; console.log(bar); // выведет 111 > // . неявно понимается как: function do_something() var bar; console.log(bar); // выведет undefined bar = 111; console.log(bar); // выведет 111 >
Глобальный объект
Глобальный объект предоставляет переменные и функции, доступные в любом месте программы. По умолчанию это те, что встроены в язык или среду исполнения.
В браузере он называется window , в Node.js — global , в другой среде исполнения может называться иначе.
Недавно globalThis был добавлен в язык как стандартизированное имя для глобального объекта, которое должно поддерживаться в любом окружении. Он поддерживается во всех основных браузерах.
Далее мы будем использовать window , полагая, что наша среда – браузер. Если скрипт может выполняться и в другом окружении, лучше будет globalThis .
Ко всем свойствам глобального объекта можно обращаться напрямую:
alert("Привет"); // это то же самое, что и window.alert("Привет");
В браузере глобальные функции и переменные, объявленные с помощью var (не let/const !), становятся свойствами глобального объекта:
var gVar = 5; alert(window.gVar); // 5 (становится свойством глобального объекта)
То же самое касается функций, объявленных с помощью синтаксиса Function Declaration (выражения с ключевым словом function в основном потоке кода, не Function Expression)
Пожалуйста, не полагайтесь на это. Такое поведение поддерживается для совместимости. В современных проектах, использующих JavaScript-модули, такого не происходит.
Если бы мы объявили переменную при помощи let , то такого бы не произошло:
let gLet = 5; alert(window.gLet); // undefined (не становится свойством глобального объекта)
Если свойство настолько важное, что вы хотите сделать его доступным для всей программы, запишите его в глобальный объект напрямую:
// сделать информацию о текущем пользователе глобальной, для предоставления доступа всем скриптам window.currentUser = < name: "John" >; // где угодно в коде alert(currentUser.name); // John // или, если у нас есть локальная переменная с именем "currentUser", // получим её из window явно (безопасно!) alert(window.currentUser.name); // John
При этом обычно не рекомендуется использовать глобальные переменные. Следует применять их как можно реже. Дизайн кода, при котором функция получает входные параметры и выдаёт определённый результат, чище, надёжнее и удобнее для тестирования, чем когда используются внешние, а тем более глобальные переменные.
Использование для полифилов
Глобальный объект можно использовать, чтобы проверить поддержку современных возможностей языка.
Например, проверить наличие встроенного объекта Promise (такая поддержка отсутствует в очень старых браузерах):
if (!window.Promise)
Если нет (скажем, используется старый браузер), мы можем создать полифил: добавить функции, которые не поддерживаются окружением, но существуют в современном стандарте.
if (!window.Promise) < window.Promise = . // собственная реализация современной возможности языка >
Итого
- Глобальный объект хранит переменные, которые должны быть доступны в любом месте программы. Это включает в себя как встроенные объекты, например, Array , так и характерные для окружения свойства, например, window.innerHeight – высота окна браузера.
- Глобальный объект имеет универсальное имя – globalThis . …Но чаще на него ссылаются по-старому, используя имя, характерное для данного окружения, такое как window (браузер) и global (Node.js).
- Следует хранить значения в глобальном объекте, только если они действительно глобальны для нашего проекта. И стараться свести их количество к минимуму.
- В браузерах, если только мы не используем модули, глобальные функции и переменные, объявленные с помощью var , становятся свойствами глобального объекта.
- Для того, чтобы код был проще и в будущем его легче было поддерживать, следует обращаться к свойствам глобального объекта напрямую, как window.x .
Как сделать глобальную переменную в js
Node.js предоставляет специальный объект global , который предоставляет доступ к глобальным, то есть доступным из каждого модуля приложения, переменным и функциям. Примерным аналогом данного объекта в javascript для браузера является объект window . Все доступные глобальные объекты можно посмотреть в документации.
Для примера создадим следующий модуль greeting.js :
const currentDate = new Date(); global.date = currentDate; module.exports.printMessage = function() < const hour = currentDate.getHours(); if(hour >16) console.log("Добрый вечер,", global.username); else if(hour > 10) console.log("Добрый день,", username); else console.log("Доброе утро,", username); >
Здесь, во-первых, происходит установка глобальной переменной date : global.date = currentDate;
Во-вторых, в модуле получаем глобальную переменную username, которая будет установлена из вне. При этом обратиться к глобальной переменной username мы можем через объект global: global.username , либо просто через имя username , так как переменная глобальная.
Определим следующий файл приложения app.js :
const greeting = require("./greeting"); global.username = "Eugene"; global.console.log(date); console.log(greeting.getMessage());
Здесь устанавливаем глобальную переменную username, которую мы получаем в модуле «greeting.js». И также выводим на консоль глобальную переменную date. Причем все глобальные функции и объекты, например, console , также доступны внутри global, поэтому мы можем написать и global.console.log() , и просто console.log() .
Запустим файл app.js:
c:\app> node app.js 2023-11-21T17:32:19.063Z Добрый вечер, Eugene c:\app>
Однако по возможности все таки рекомендуется избегать определения и использования глобальных переменных, и преимущественно ориентироваться на создание переменных, инкапсулированных в рамках отдельных модулей.
Как сделать глобальную переменную в js
Уже отмечалось (см., например, Заметка 5. Переменные), что код JavaScript выполняется в контексте глобального объекта, и таким объектом является объект window (описывает окно браузера), если мы программируем для браузера.
Это означает, что все глобальные переменные становятся свойствами объекта window . Можно было бы и не говорить дополнительно о функциях, так как функции JavaScript мало чем отличаются от переменных, но все же скажем: глобальные функции становятся методами объекта window .
Замечание 1. Вспомним, что «метод» — это условное название свойства объекта в том случае, когда значением свойства является функция.
Замечание 2. Вспомним и то, что слова «значением свойства является функция», означают на самом деле, что значением свойства является ссылка на функцию, которую интерпретатор JavaScript располагает где-то в памяти. Свойство или переменная содержат сами значения только для данных элементарного типа. В случае объекта (а функция — это объект) переменные и свойства хранят ссылки на него, а сам объект располагается где-то в памяти.
Так, если мы записываем код:
var x = kv(10); // 100
то тем самым добавляем в объект window два свойства с именами x и kv .
К переменной x можно обращаться, как свойству window.x , а к функции kv , как к методу window.kv .
Такое поведение среды, в которой работает код, таит в себе реальную опасность — можно случайно перекрыть (переопределить) встроенное свойство или метод объекта window .
Чтобы избежать подобной неприятности, программисты стараются не использовать в своем коде более одного глобального имени, а то и вовсе обходятся без глобальных имен.
Как обойтись одним глобальным именем
; // Объявление единственного глобального имени objRobotland.kv = function (t) < return t*t;>objRobotland.x = objRobotland.kv(10);
В этом коде задействовано только одно глобальное имя — objRobotland . Это имя созданного объекта. Все переменные и функции описываются как его свойства и методы.
Для построения уникального глобального имени можно задействовать адрес электронной почты (или домен) автора:
; objRobotlandPereslavlRu.kv = function (t) < return t*t;>objRobotlandPereslavlRu.x = objRobotlandPereslavlRu.kv(10);
Такая конструкция позволит, практически на 100%, избежать совпадения построенного идентификатора с глобальными именами сторонних кодов, если мы собираемся их использовать на наших страницах. И позволит без конфликтов задействовать наши коды другими программистами.
Если мы не собираемся писать (и использовать) публичные коды, то можно, конечно, обойтись и более короткими идентификаторами:
; objRobot.kv = function (t) < return t*t;>objRobot.x = objRobot.kv(10);
Как обойтись без глобальных имен
Если код должен быть выполнен только один раз, можно поместить его внутрь функционального литерала (безымянной функции) и вызвать функциональный литерал на исполнение:
var x = kv(10); alert(x); // 100 >)(); alert(x); // Сообщение об ошибке
Здесь x и kv — это локальные переменные, а глобальной переменной нет ни одной.
Функция alert , которую мы уже много раз использовали при отладке своих кодов, является встроенным методом объекта window , то есть более точное написание этой функции — window.alert . Но в написании свойств и методов глобального объекта его имя можно опускать, поэтому мы записываем вызов этого метода более кратко: alert .
Часто приходится выполнять какие-то действия над объектами страницы. Это правомочно лишь после того, как браузер страницу построит. Значит, код должен начинать работу не сразу, а только после наступления события onload .
Можно, в качестве обработчика события onload , написать функциональный литерал, и в нём выполнить всё необходимое:
var x = kv(10); alert(x); // 100 >;
Замечание 1. При наступлении события браузер выполняет функцию-обработчик, ссылку на которую содержит соответствующее свойство объекта, построенного для элемента, на котором событие возникло. Так, после загрузки документа в окно, браузер выполняет функцию, заданную свойством window.onload . Таким образом, если нужно что-то сделать после полной загрузки документа, поместите действия в некую функцию f и присвойте ссылку на нее свойству window.onload : window.onload = f . Можно не именовать функцию, а задать ее функциональным литералом в правой части равенства: window.onload = function()<. >; . Именно так и сделано в приведённом выше примере.
Замечание 2. Можно было бы вместо window.onload записывать просто onload , но такая запись смотрелась бы «подозрительно», словно onload — это наша собственная глобальная переменная, а не встроенное свойство глобального объекта.
Замечание 3. Обработчик события onload можно задавать и как значение одноименного атрибута в открывающем теге элемента BODY : .
Функциональный литерал будет вызван на исполнение после наступления события onload , то есть после того, как браузер построит объектную модель документа и покажет его в своем окне.