- Эта статья в основном посвящена области видимости в ванильном JavaScript и различным способам ее использования в наших интересах. Есть много способов взглянуть на область видимости, чтобы попытаться лучше понять ее, мой мозг всегда приходит к аналогии, что если ваше приложение — это автомобиль, то область видимости — это различные отсеки внутри автомобиля. Глобальная область видимости — это салон вашего автомобиля, из нее вы можете открыть капот и багажник, но вы делаете это с помощью «функции», потому что находитесь в глобальной области видимости. Ваш багажник, как цепочка блоков, доступен только внутри себя (если только ваши задние сиденья не складываются, чтобы дать доступ к багажнику, как именование переменной var внутри блока, но в моем примере я не ссылаюсь на такой автомобиль или именование переменной var внутри моего блока), вы можете упаковать столько, сколько хотите в багажник, но если вы хотите получить доступ к нему внутри салона, вам придется вытащить его из багажника и поместить в глобальную область видимости. Ваш моторный отсек похож на функциональную область, он также самодостаточен, но в нем есть множество систем, работающих друг с другом и передающих информацию дочерним подсистемам, чтобы все работало.
Глобальная область видимости
- Глобальная область видимости может быть использована довольно безопасно в небольших приложениях, но по мере роста вашего приложения объявление переменных в глобальной области видимости может привести к множеству отладок и головной боли в дальнейшем. Лучшей практикой является объявление переменных в пределах области видимости, где они будут использоваться, чтобы избежать чрезмерной записи их значения или обращения к неправильной переменной с помощью функции. Вернемся к моему примеру выше, если вы подумаете о внутреннем пространстве вашего автомобиля, когда вы сидите на водительском сиденье, у вас есть доступ ко всему автомобилю, вы можете дотянуться и открыть перчаточный ящик, вы можете воспользоваться замком капота и багажника, и все это находится на расстоянии вытянутой руки, что очень приятно. Однако вы не можете вытащить что-то из моторного отсека или из багажника с водительского места, но вы можете воздействовать на эти отсеки с водительского места.
//example 1
const varible1= "Hello world"
function showInConsoleLog(){
console.log(varible1)
}
showInConsoleLog()
excepted return in console
console Hello World
//example 2
const firstNumber = 2
const secondNumber = 4
function addNumberTogether(){
const numbersAddedTogether = (firstNumber + secondNumber)
console.log(numbersAddedTogether)
}
addNumberTogether()
excepted return in console
console 6
//example 3
const firstNumber = 2
const secondNumber = 4
function addNumberTogether(){
const numbersAddedTogether = (firstNumber + secondNumber)
}
/*
This will not show up in console even though the function is invoked and the numbers are added together.
vvv The value of numbersAddedTogether is not declared Globally, so it cannot be seen by the console.log() which is in global scope.
*/
console.log(numbersAddedTogether)
addNumberTogether()
excepted return in console
ReferenceError: numbersAddedTogether is not defined
}
Область действия блока
- Область видимости блока и область видимости функции тесно связаны, но имеют некоторые различия. Область видимости функции может передавать аргумент при вызове и затем использовать вызванный аргумент в пределах своей области видимости. Область видимости блока отсекает доступ извне к тому, что находится между фигурными скобками. Это полезно, если у вас есть определенные переменные, к которым вы хотите получить доступ только в пределах области видимости блока, или если у вас есть две переменные с одинаковым именем с разными значениями, доступными приложению в зависимости от того, как разрешается код. Это опять же не так, если ваша переменная объявлена с помощью var, а не let или const. Область видимости блока полезна для создания утверждений блока, что позволяет вашему коду использовать и или разрешать несколько утверждений в местах, где javascript исключает только одно утверждение. Примером могут служить операторы if и for, где мы можем назвать переменную, на которую будет сделана ссылка для проверки, но не иметь доступа к ней за пределами этого оператора. Пример 3 в глобальной области видимости демонстрирует область видимости блока, так же как и пример ниже
//example 1
function increaseNumber() {
for (let x = 0; x < 5; x++) {
console.log(x)
}
}
increaseNumber()
excepted return in console
console 0
console 1
console 2
console 3
console 4
//example 2
function increaseNumber() {
for (let x = 0; x < 5; x++) {
}
/*
This will not show up in console even though x is being increased and the code does know that,
vvv x is not defined in within scope of the console log so it can not reference it vvv
*/
console.log(x)
}
increaseNumber()
excepted return in console
ReferenceError: x is not defined
Область видимости функций
- Область видимости функций немного сложнее, чем глобальная и блочная область видимости. Область видимости функций — это как моторный отсек вашего автомобиля. Подумайте о приборной панели — она дает вам представление о том, что происходит внутри вашего моторного отсека. Это похоже на возврат в функции, объявленной в глобальной области видимости. Это позволяет просматривать результаты функции вне функции, но это не означает, что у вас есть доступ к внутренним переменным датчика, только к его результату. Однако из моторного отсека поступает больше информации, к которой у вас нет доступа с приборной панели, и это похоже на функцию, объявленную внутри функции, результаты которой вы не можете напрямую увидеть на приборной панели. Даже если эта информация может быть критически важной для обеспечения работоспособности вашего автомобиля, она не должна быть видна вам (глобальная область видимости). Теперь поговорим о педали газа — это функция, которая объявлена в глобальной области видимости, но может влиять на работу двигателя. Это похоже на использование аргумента, переданного в функцию, для использования переменных, объявленных в глобальной области видимости функции. Когда функция вызывается в другой области видимости, она может получить доступ к данным в этой области видимости, если при вызове ей передаются данные в качестве аргумента. Возвращаясь к аналогии, когда вы нажимаете на педаль газа, вы говорите своему автомобилю, что хотите ехать быстрее, он принимает эту функцию и передает ее двигателю. Затем двигатель принимает решение, выполняя эту функцию с другими данными в качестве аргумента, если это возможно сделать. Таким образом, ваша функция (педаль газа) фактически имеет доступ к данным, которые находятся в другой области видимости функции (моторный отсек), пока функция (педаль газа) вызывается в другой области видимости функции (моторный отсек) и ей передаются эти данные в качестве аргумента. Есть некоторые проблемы с этой аналогией, если вы действительно разберете ее на части, но, надеюсь, этот краткий обзор помог кому-то понять область видимости немного лучше.
//example 1
function getNameFromFunctionScope(name){
console.log(name)
}
function createFirstNameToRetrieve(){
const firstName = 'John'
const middleName = firstName + ' Paper'
const lastName =middleName + ' Smith'
getNameFromFunctionScope(lastName)
}
createFirstNameToRetrieve()
excepted return in console
console John Paper Smith
/*
^^^ In this example even though the console.log() is in a separate scope lastName is available to it because, ^^^
it is invoked within the scope of lastName with lastName as an argument.
That argument is referenced as a parameter in the function and then console logged
*/
//example 2
function getNameFromFunctionScope(name){
console.log(name)
}
function createFirstNameToRetrieve(){
const firstName = 'John'
const middleName = firstName + ' Paper'
const lastName =middleName + ' Smith'
getNameFromFunctionScope(middleName)
}
createFirstNameToRetrieve()
excepted return in console
console John Paper
/*
Similar to the above example. This is to show that even though the function creates a full name
we can access the variables separately, if we use that varible as the parameter when we invoke our function.
*/