Что будет если внутри функции объявлена переменная с тем же именем что и внешняя переменная
Перейти к содержимому

Что будет если внутри функции объявлена переменная с тем же именем что и внешняя переменная

Функции

Зачастую нам надо повторять одно и то же действие во многих частях программы.

Например, необходимо красиво вывести сообщение при приветствии посетителя, при выходе посетителя с сайта, ещё где-нибудь.

Чтобы не повторять один и тот же код во многих местах, придуманы функции. Функции являются основными «строительными блоками» программы.

Примеры встроенных функций вы уже видели – это alert(message) , prompt(message, default) и confirm(question) . Но можно создавать и свои.

Объявление функции

Для создания функций мы можем использовать объявление функции.

Пример объявления функции:

Вначале идёт ключевое слово function , после него имя функции, затем список параметров в круглых скобках через запятую (в вышеприведённом примере он пустой) и, наконец, код функции, также называемый «телом функции», внутри фигурных скобок.

Наша новая функция может быть вызвана по её имени: showMessage() .

Вызов showMessage() выполняет код функции. Здесь мы увидим сообщение дважды.

Этот пример явно демонстрирует одно из главных предназначений функций: избавление от дублирования кода.

Если понадобится поменять сообщение или способ его вывода – достаточно изменить его в одном месте: в функции, которая его выводит.

Локальные переменные

Переменные, объявленные внутри функции, видны только внутри этой функции.

Внешние переменные

У функции есть доступ к внешним переменным, например:

Функция обладает полным доступом к внешним переменным и может изменять их значение.

Внешняя переменная используется, только если внутри функции нет такой локальной.

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

Переменные, объявленные снаружи всех функций, такие как внешняя переменная userName в вышеприведённом коде – называются глобальными.

Глобальные переменные видимы для любой функции (если только их не перекрывают одноимённые локальные переменные).

Желательно сводить использование глобальных переменных к минимуму. В современном коде обычно мало или совсем нет глобальных переменных. Хотя они иногда полезны для хранения важнейших «общепроектовых» данных.

Параметры

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

В нижеприведённом примере функции передаются два параметра: from и text .

Когда функция вызывается в строках (*) и (**) , переданные значения копируются в локальные переменные from и text . Затем они используются в теле функции.

Вот ещё один пример: у нас есть переменная from , и мы передаём её функции. Обратите внимание: функция изменяет значение from , но это изменение не видно снаружи. Функция всегда получает только копию значения:

Значение передаваемое в качестве параметра функции, также называется аргументом.

Параметр – это переменная, указанная в круглых скобках в объявлении функции. Аргумент – это значение, которое передаётся функции при её вызове.

Мы объявляем функции со списком параметров, затем вызываем их, передавая аргументы.

В приведённом выше примере можно было бы сказать: "функция showMessage объявляется с двумя параметрами, затем вызывается с двумя аргументами: from и "Привет" ".

Параметры по умолчанию

Если параметр не указан, то его значением становится undefined .

Например, вышеупомянутая функция showMessage(from, text) может быть вызвана с одним аргументом:

Это не приведёт к ошибке. Такой вызов выведет "*Аня*: undefined" . В вызове не указан параметр text , поэтому предполагается, что text === undefined .

Если мы хотим задать параметру text значение по умолчанию, мы должны указать его после = :

Теперь, если параметр text не указан, его значением будет "текст не добавлен"

В данном случае "текст не добавлен" это строка, но на её месте могло бы быть и более сложное выражение, которое бы вычислялось и присваивалось при отсутствии параметра. Например:

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

В примере выше anotherFunction() будет вызываться каждый раз, когда showMessage() вызывается без параметра text .

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

Например, явная проверка на undefined :

…Или с помощью оператора || :

Возврат значения

Функция может вернуть результат, который будет передан в вызвавший её код.

Простейшим примером может служить функция сложения двух чисел:

Директива return может находиться в любом месте тела функции. Как только выполнение доходит до этого места, функция останавливается, и значение возвращается в вызвавший её код (присваивается переменной result выше).

Вызовов return может быть несколько, например:

Возможно использовать return и без значения. Это приведёт к немедленному выходу из функции.

В коде выше, если checkAge(age) вернёт false , showMovie не выполнит alert .

Если функция не возвращает значения, это всё равно, как если бы она возвращала undefined :

Пустой return аналогичен return undefined :

Для длинного выражения в return может быть заманчиво разместить его на нескольких отдельных строках, например так:

Код не выполнится, потому что интерпретатор JavaScript подставит точку с запятой после return . Для него это будет выглядеть так:

Таким образом, это фактически стало пустым return .

Если мы хотим, чтобы возвращаемое выражение занимало несколько строк, нужно начать его на той же строке, что и return . Или, хотя бы, поставить там открывающую скобку, вот так:

И тогда всё сработает, как задумано.

Выбор имени функции

Функция – это действие. Поэтому имя функции обычно является глаголом. Оно должно быть простым, точным и описывать действие функции, чтобы программист, который будет читать код, получил верное представление о том, что делает функция.

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

Например, функции, начинающиеся с "show" обычно что-то показывают.

Функции, начинающиеся с…

  • "get…" – возвращают значение,
  • "calc…" – что-то вычисляют,
  • "create…" – что-то создают,
  • "check…" – что-то проверяют и возвращают логическое значение, и т.д.

Примеры таких имён:

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

Функция должна делать только то, что явно подразумевается её названием. И это должно быть одним действием.

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

Несколько примеров, которые нарушают это правило:

  • getAge – будет плохим выбором, если функция будет выводить alert с возрастом (должна только возвращать его).
  • createForm – будет плохим выбором, если функция будет изменять документ, добавляя форму в него (должна только создавать форму и возвращать её).
  • checkPermission – будет плохим выбором, если функция будет отображать сообщение с текстом доступ разрешён/запрещён (должна только выполнять проверку и возвращать её результат).

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

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

Например, во фреймворке jQuery есть функция с именем $ . В библиотеке Lodash основная функция представлена именем _ .

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

Функции == Комментарии

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

Небольшие функции не только облегчают тестирование и отладку – само существование таких функций выполняет роль хороших комментариев!

Например, сравним ниже две функции showPrimes(n) . Каждая из них выводит простое число до n .

Первый вариант использует метку nextPrime :

Второй вариант использует дополнительную функцию isPrime(n) для проверки на простое:

Второй вариант легче для понимания, не правда ли? Вместо куска кода мы видим название действия ( isPrime ). Иногда разработчики называют такой код самодокументируемым.

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

Итого

Объявление функции имеет вид:

  • Передаваемые значения копируются в параметры функции и становятся локальными переменными.
  • Функции имеют доступ к внешним переменным. Но это работает только изнутри наружу. Код вне функции не имеет доступа к её локальным переменным.
  • Функция может возвращать значение. Если этого не происходит, тогда результат равен undefined .

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

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

  • Имя функции должно понятно и чётко отражать, что она делает. Увидев её вызов в коде, вы должны тут же понимать, что она делает, и что возвращает.
  • Функция – это действие, поэтому её имя обычно является глаголом.
  • Есть много общепринятых префиксов, таких как: create… , show… , get… , check… и т.д. Пользуйтесь ими как подсказками, поясняющими, что делает функция.

Функции являются основными строительными блоками скриптов. Мы рассмотрели лишь основы функций в JavaScript, но уже сейчас можем создавать и использовать их. Это только начало пути. Мы будем неоднократно возвращаться к функциям и изучать их всё более и более глубоко.

Задачи

Обязателен ли "else"?

Следующая функция возвращает true , если параметр age больше 18 .

В ином случае она запрашивает подтверждение через confirm и возвращает его результат:

Будет ли эта функция работать как-то иначе, если убрать else ?

Есть ли хоть одно отличие в поведении этого варианта?

Оба варианта функций работают одинаково, отличий нет.

Перепишите функцию, используя оператор ‘?’ или ‘||’

Следующая функция возвращает true , если параметр age больше 18 .

В ином случае она задаёт вопрос confirm и возвращает его результат.

Перепишите функцию, чтобы она делала то же самое, но без if , в одну строку.

Что в коробке? Как работают функции в JavaScript

Знакомимся с фундаментальным строительным блоком любого приложения на JavaScript — функцией.

Что в коробке? Как работают функции в JavaScript, изображение №1

Что такое функция

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

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

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

Как объявить функцию

Функция объявляется с помощью команды function . После чего мы именуем функцию и в скобках записываем ее параметры.

Синтаксис функции на JavaScript

Например, функция, которая вызывает предупреждение:

Код функции с предупреждением

Что в коробке? Как работают функции в JavaScript, изображение №2

Как вызвать функцию

Функцию вызывают по имени. Например, чтобы вызывать функцию из нашего примера, нужно после функции написать showAlert();

Параметры и аргументы

Аргументы

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

Пример использования параметров и аргументов

В примере мы используем два параметра: from и text . Затем в теле функции соединяем from + ‘, ‘ + text . А снаружи функции присваиваем им аргументы и выводим на экран.

Передачи одной функции в другую

В функцию можно передать значение другой функции. Например:

Примеры передачи одной функции в другую

В примере задано две функции:

  1. getDomNodesBySelector — преобразует найденные селекторы на веб странице в массив.
  2. applyDiscount — считает какую-то величину и берет данные для этого из функции getDomNodesBySelector .

Колбэки

Строки кода в языке JavaScript выполняются по очереди. Например:

Пример функций, которые выполняются по порядку

Но бывают такие случаи, когда нам необходимо отсрочить функцию one() , чтобы первой выполнилась two() . Для этого можно использовать setTimeout .

Пример функций, которые выполняются не по порядку

Вызов функции с отсрочкой называется колбэк ( callback ).

Колбэк передают в виде параметра. Например:

Функция myHomework имеет два параметра subject и callback .

Затем мы вызываем параметр subject , а параметр callback вызовем функцией myHomeworkFinished .

Когда код выполнится, появятся два предупреждения: Starting my math homework и Finished my homework .

Что в коробке? Как работают функции в JavaScript, изображение №3

Локальные переменные

Локальные переменные видны только внутри тела функции. За пределами функции эти переменные уже не работают.

Пример кода с локальной переменной

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

В первом случае — получаем результат работы функции.

Во втором случае — получаем ошибку, потому что переменную видно только внутри функции.

Внешние переменные

Давайте возьмем пример выше. Оставим внутри функции значение переменной message . А за пределами функции заведем другую переменную и назовем ее message .

Пример кода с локальной и внешней переменной

В коде у нас две переменные с одинаковым именем. Но наш сценарий будет считать их разными переменными.

В первом случае переменная будет видна программе только внутри функции showMessage() , во втором случае переменная будет видна всей программе.

Параметры по умолчанию

Когда мы указали параметр и не присвоили ему аргумент, то его значение будет undefined .

Пример кода с параметром по умолчанию

В примере параметру text мы не передали значение аргумента. Поэтому в результате мы видим аргумент параметра from и undefined .

Возврат значения

Вернуть значение функции можно с помощью директивы return в теле функции. Например, напишем функцию, которая складывает два параметра.

Пример возврата значения функции с помощью директивы return

В примере мы говорим функции, что необходимо возвращать сумму значений аргументов с помощью директивы return .

Необходимо помнить, что после return выполнение операций в функции прекращается. Поэтому, с помощью return можно прерывать функции.

Функция, которая возвращает функцию

Функцию из предыдущего примера можно записать так:

Пример функции, которая возвращает функцию

  1. Создали переменную generateSumFinder и присвоили ей значение стрелочной функции. Когда мы видим значок => , перед нами стрелочная функция.
  2. Внутри функции создали переменную sum . Это локальная переменная и видна только внутри функции и присвоили ей значение стрелочной функции, которая складывает аргументы a и b.
  3. Вернули переменную sum .
  4. За пределами функции создали переменную sum . Это внешняя переменная и она не зависит от переменной внутри функции. Этой переменной мы присвоили значение функции generateSumFinder .

Рекурсия

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

Функция будет вызываться каждый раз, пока значение ее параметра i больше 1 – это рекурсивный случай. Или вызывается при базовом случае при i<=1 .

Перегрузка функций в JavaScript

У перегруженных функций одинаковые имена, но разные параметры. JavaScript не поддерживает перегрузку.

Пример функции без перегрузки

Несмотря на то, что в первой функции один параметр, вывод аргументов этой функции выведет два параметра. Как вы помните, второй ее параметр будет undefined .

В JavaScript есть способы, как перегрузить функцию. Для этого используют метод arguments.length .

Пример функции с перегрузкой

В примере с помощью метода arguments.length мы узнаем количество параметров в функции и выводим столько параметров, сколько аргументов мы задаем.

Выбор имени функции

Чтобы выбрать имя функции, необходимо следовать правилам:

Что в коробке? Как работают функции в JavaScript, изображение №4

Комментарии в функции

Комментарии нужны, чтобы кто-то кроме вас понимал, что происходит в функции.

Пример комментария в функции

Замыкания

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

Пример замыкания функции на внешней переменной

В примере функция sayHi() будет оперировать со вторым значением переменной name . Таким образом, функция замыкает свое действие на известной переменной, где бы не задали ее значение.

Приведем еще один пример:

Пример замыкания функции на внутренней переменной

В примере функция makeWorker() замыкается на внутренней переменной name = «Nikolay» . Поэтому при инициализации переменных, следует обращать внимание, какая функция будет ими пользоваться и на какой из них будет замыкаться.

Стрелочные функции

Функцию можно задать не только с помощью слова function . Есть способ короче, для этого используют значок => .

Пример функции, которая складывает параметры a и b

Если параметр в функции один, то скобки можно не писать.

Пример записи стрелочной функции с одним параметром n

Если параметров нет, то пишут круглые скобки.

Пример стрелочной функции без параметров

Лексика this

В стрелочных функциях нет лексики this. Если происходит обращение к this , его значение берется снаружи.

Пример использования this в стрелочной функции

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

Что будет если внутри функции объявлена переменная с тем же именем что и внешняя переменная

  • Open with Desktop
  • View raw
  • Copy raw contents Copy raw contents

Copy raw contents

Copy raw contents

Зачастую нам надо повторять одно и то же действие во многих частях программы.

Например, красиво вывести сообщение необходимо при приветствии посетителя, при выходе посетителя с сайта, ещё где-нибудь.

Чтобы не повторять один и тот же код во многих местах, придуманы функции. Функции являются основными «строительными блоками» программы.

Примеры встроенных функций вы уже видели — это alert(message) , prompt(message, default) и confirm(question) . Но можно создавать и свои.

Пример объявления функции:

Вначале идет ключевое слово function , после него имя функции, затем список параметров в скобках (в примере выше он пустой) и тело функции — код, который выполняется при её вызове.

Объявленная функция доступна по имени, например:

Этот код выведет сообщение два раза. Уже здесь видна главная цель создания функций: избавление от дублирования кода.

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

Функция может содержать локальные переменные, объявленные через var . Такие переменные видны только внутри функции:

Блоки if/else , switch , for , while , do..while не влияют на область видимости переменных.

При объявлении переменной в таких блоках, она всё равно будет видна во всей функции.

Неважно, где именно в функции и сколько раз объявляется переменная. Любое объявление срабатывает один раз и распространяется на всю функцию.

Объявления переменных в примере выше можно передвинуть вверх, это ни на что не повлияет:

Функция может обратиться ко внешней переменной, например:

Доступ возможен не только на чтение, но и на запись. При этом, так как переменная внешняя, то изменения будут видны и снаружи функции:

Конечно, если бы внутри функции, в строке (1) , была бы объявлена своя локальная переменная var userName , то все обращения использовали бы её, и внешняя переменная осталась бы неизменной.

Переменные, объявленные на уровне всего скрипта, называют «глобальными переменными».

В примере выше переменная userName — глобальная.

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

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

При вызове функции ей можно передать данные, которые та использует по своему усмотрению.

Например, этот код выводит два сообщения:

Параметры копируются в локальные переменные функции.

Например, в коде ниже есть внешняя переменная from , значение которой при запуске функции копируется в параметр функции с тем же именем. Далее функция работает уже с параметром:

Аргументы по умолчанию

Функцию можно вызвать с любым количеством аргументов.

Если параметр не передан при вызове — он считается равным undefined .

Например, функцию показа сообщения showMessage(from, text) можно вызвать с одним аргументом:

При этом можно проверить, и если параметр не передан — присвоить ему значение «по умолчанию»:

При объявлении функции необязательные аргументы, как правило, располагают в конце списка.

Для указания значения «по умолчанию», то есть, такого, которое используется, если аргумент не указан, используется два способа:

Можно проверить, равен ли аргумент undefined , и если да — то записать в него значение по умолчанию. Этот способ продемонстрирован в примере выше.

Второй способ считает, что аргумент отсутствует, если передана пустая строка, 0 , или вообще любое значение, которое в логическом контексте является false .

Если аргументов передано больше, чем надо, например showMessage(«Маша», «привет», 1, 2, 3) , то ошибки не будет. Но, чтобы получить такие «лишние» аргументы, нужно будет прочитать их из специального объекта arguments , который мы рассмотрим в главе info:arguments-pseudoarray.

Функция может возвратить результат, который будет передан в вызвавший её код.

Например, создадим функцию calcD , которая будет возвращать дискриминант квадратного уравнения по формуле b 2 — 4ac :

Для возврата значения используется директива return .

Она может находиться в любом месте функции. Как только до неё доходит управление — функция завершается и значение передается обратно.

Вызовов return может быть и несколько, например:

Директива return может также использоваться без значения, чтобы прекратить выполнение и выйти из функции.

В коде выше, если сработал if , то строка (*) и весь код под ней никогда не выполнится, так как return завершает выполнение функции.

««smart header В случае, когда функция не вернула значение или `return` был без аргументов, считается что она вернула `undefined`:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *