The JavaScript Global Object
JavaScript provides a global object which has a set of properties, functions and objects that are accessed globally, without a namespace.
- decodeURI()
- decodeURIComponent()
- encodeURI()
- encodeURIComponent()
- eval()
- isFinite()
- isNaN()
- parseFloat()
- parseInt()
- Error
- EvalError
- RangeError
- ReferenceError
- SyntaxError
- TypeError
- URIError
I describe errors on this JavaScript Errors reference post.
Let’s now describe here the global properties and functions.
Infinity
Infinity in JavaScript is a value that represents infinity.
Positive infinity. To get negative infinity, use the – operator: -Infinity .
Those are equivalent to Number.POSITIVE_INFINITY and Number.NEGATIVE_INFINITY .
Adding any number to Infinity , or multiplying Infinity for any number, still gives Infinity .
NaN
The global NaN value is an acronym for Not a Number . It’s returned by operations such as zero divided by zero, invalid parseInt() operations, or other operations.
parseInt() //NaN parseInt('a') //NaN 0/0 //NaN
A special thing to consider is that a NaN value is never equal to another NaN value. You must use the isNaN() global function to check if a value evaluates to NaN :
NaN === NaN //false 0/0 === NaN //false isNaN(0/0) //true
undefined
The global undefined property holds the primitive value undefined .
Running a function that does not specify a return value returns undefined :
const test = () => <> test() //undefined
Unlike NaN , we can compare an undefined value with undefined , and get true:
It’s common to use the typeof operator to determine if a variable is undefined:
decodeURI()
Performs the opposite operation of encodeURI()
decodeURIComponent()
Performs the opposite operation of encodeURIComponent()
encodeURI()
This function is used to encode a complete URL. It does encode all characters to their HTML entities except the ones that have a special meaning in a URI structure, including all characters and digits, plus those special characters:
encodeURI("http://flaviocopes.com/ hey!/") //"http://flaviocopes.com/%20hey!/"
encodeURIComponent()
Similar to encodeURI() , encodeURIComponent() is meant to have a different job.
Instead of being used to encode an entire URI, it encodes a portion of a URI.
It does encode all characters to their HTML entities except the ones that have a special meaning in a URI structure, including all characters and digits, plus those special characters:
encodeURIComponent("http://www.example.org/a file with spaces.html") // "http%3A%2F%2Fwww.example.org%2Fa%20file%20with%20spaces.html"
eval()
This is a special function that takes a string that contains JavaScript code, and evaluates / runs it.
This function is very rarely used and for a reason: it can be dangerous.
I recommend to read this article on the subject.
isFinite()
Returns true if the value passed as parameter is finite.
isFinite(1) //true isFinite(Number.POSITIVE_INFINITY) //false isFinite(Infinity) //false
isNaN()
Returns true if the value passed as parameter evaluates to NaN .
isNaN(NaN) //true isNaN(Number.NaN) //true isNaN('x') //true isNaN(2) //false isNaN(undefined) //true
This function is very useful because a NaN value is never equal to another NaN value. You must use the isNaN() global function to check if a value evaluates to NaN :
0/0 === NaN //false isNaN(0/0) //true
parseFloat()
Like parseInt() , parseFloat() is used to convert a string value into a number, but retains the decimal part:
parseFloat('10,000', 10) //10 ❌ parseFloat('10.00', 10) //10 ✅ (considered decimals, cut) parseFloat('10.000', 10) //10 ✅ (considered decimals, cut) parseFloat('10.20', 10) //10.2 ✅ (considered decimals) parseFloat('10.81', 10) //10.81 ✅ (considered decimals) parseFloat('10000', 10) //10000 ✅
parseInt()
This function is used to convert a string value into a number.
Another good solution for integers is to call the parseInt() function:
const count = parseInt('1234', 10) //1234
Don’t forget the second parameter, which is the radix, always 10 for decimal numbers, or the conversion might try to guess the radix and give unexpected results.
parseInt() tries to get a number from a string that does not only contain a number:
but if the string does not start with a number, you’ll get NaN (Not a Number):
Also, just like Number it’s not reliable with separators between the digits:
parseInt('10,000', 10) //10 ❌ parseInt('10.00', 10) //10 ✅ (considered decimals, cut) parseInt('10.000', 10) //10 ✅ (considered decimals, cut) parseInt('10.20', 10) //10 ✅ (considered decimals, cut) parseInt('10.81', 10) //10 ✅ (considered decimals, cut) parseInt('10000', 10) //10000 ✅
Глобальный объект
Глобальный объект предоставляет переменные и функции, доступные в любом месте программы. По умолчанию это те, что встроены в язык или среду исполнения.
В браузере он называется 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 (такая поддержка отсутствует в очень старых браузерах):
Если нет (скажем, используется старый браузер), мы можем создать полифил: добавить функции, которые не поддерживаются окружением, но существуют в современном стандарте.
Итого
- Глобальный объект хранит переменные, которые должны быть доступны в любом месте программы. Это включает в себя как встроенные объекты, например, Array , так и характерные для окружения свойства, например, window.innerHeight – высота окна браузера.
- Глобальный объект имеет универсальное имя – globalThis . …Но чаще на него ссылаются по-старому, используя имя, характерное для данного окружения, такое как window (браузер) и global (Node.js).
- Следует хранить значения в глобальном объекте, только если они действительно глобальны для нашего проекта. И стараться свести их количество к минимуму.
- В браузерах, если только мы не используем модули, глобальные функции и переменные, объявленные с помощью var , становятся свойствами глобального объекта.
- Для того, чтобы код был проще и в будущем его легче было поддерживать, следует обращаться к свойствам глобального объекта напрямую, как window.x .
Global object
The global object provides variables and functions that are available anywhere. By default, those that are built into the language or the environment.
In a browser it is named window , for Node.js it is global , for other environments it may have another name.
Recently, globalThis was added to the language, as a standardized name for a global object, that should be supported across all environments. It’s supported in all major browsers.
We’ll use window here, assuming that our environment is a browser. If your script may run in other environments, it’s better to use globalThis instead.
All properties of the global object can be accessed directly:
alert("Hello"); // is the same as window.alert("Hello");
In a browser, global functions and variables declared with var (not let/const !) become the property of the global object:
var gVar = 5; alert(window.gVar); // 5 (became a property of the global object)
Function declarations have the same effect (statements with function keyword in the main code flow, not function expressions).
Please don’t rely on that! This behavior exists for compatibility reasons. Modern scripts use JavaScript modules where such a thing doesn’t happen.
If we used let instead, such thing wouldn’t happen:
let gLet = 5; alert(window.gLet); // undefined (doesn't become a property of the global object)
If a value is so important that you’d like to make it available globally, write it directly as a property:
// make current user information global, to let all scripts access it window.currentUser = < name: "John" >; // somewhere else in code alert(currentUser.name); // John // or, if we have a local variable with the name "currentUser" // get it from window explicitly (safe!) alert(window.currentUser.name); // John
That said, using global variables is generally discouraged. There should be as few global variables as possible. The code design where a function gets “input” variables and produces certain “outcome” is clearer, less prone to errors and easier to test than if it uses outer or global variables.
Using for polyfills
We use the global object to test for support of modern language features.
For instance, test if a built-in Promise object exists (it doesn’t in really old browsers):
If there’s none (say, we’re in an old browser), we can create “polyfills”: add functions that are not supported by the environment, but exist in the modern standard.
Summary
- The global object holds variables that should be available everywhere. That includes JavaScript built-ins, such as Array and environment-specific values, such as window.innerHeight – the window height in the browser.
- The global object has a universal name globalThis . …But more often is referred by “old-school” environment-specific names, such as window (browser) and global (Node.js).
- We should store values in the global object only if they’re truly global for our project. And keep their number at minimum.
- In-browser, unless we’re using modules, global functions and variables declared with var become a property of the global object.
- To make our code future-proof and easier to understand, we should access properties of the global object directly, as window.x .
Comments
- If you have suggestions what to improve — please submit a GitHub issue or a pull request instead of commenting.
- If you can’t understand something in the article – please elaborate.
- To insert few words of code, use the tag, for several lines – wrap them in tag, for more than 10 lines – use a sandbox (plnkr, jsbin, codepen…)