Function что это
Перейти к содержимому

Function что это

  • автор:

Функции

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

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

Больше подробностей и примеров можно найти в руководстве по функциям в JavaScript.

Описание

Каждая функция в JavaScript — это объект Function. О свойствах и методах объектов Function можно прочитать в статье Function .

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

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

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

/* Объявляем функцию 'myFunc' */ function myFunc(theObject)  theObject.brand = "Toyota"; > /* * Объявляем переменную 'mycar'; * создаём и инициализируем новый Object; * приравниваем 'mycar' к ссылке на него */ var mycar =  brand: "Honda", model: "Accord", year: 1998, >; /* Выведет 'Honda' */ console.log(mycar.brand); /* Передаём ссылку на объект в функцию */ myFunc(mycar); /* * Выведет 'Toyota', так как значение свойства 'brand' * было изменено внутри функции. */ console.log(mycar.brand); 

Ключевое слово this не ссылается на функцию, которая выполняется в данный момент, поэтому вы должны обращаться к объектами Function по имени, даже внутри тела самой функции.

Определение функций

Есть несколько способов определить функцию:

Объявление функции (инструкция function )

Специальный синтаксис для объявления функций (более подробно: function statement):

function name([param[, param[, . param]]])

Имя аргумента, передаваемого в функцию. У функции может быть не более 255 аргументов.

Инструкции, из которых состоит тело функции.

Функция-выражение (оператор function )

Функция-выражение похожа на определение функции и имеет такой же синтаксис (более подробно: function operator):

function [name]([param] [, param] [. param])

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

Имя аргумента, передаваемого в функцию. У функции может быть не более 255 аргументов.

Инструкции, из которых состоит тело функции.

Стрелочная функция-выражение (=>)

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

Стрелочные функции отличаются более кратким синтаксисом и тем, что они лексически связывают значение своего this (подробнее об этом в статье Стрелочные функции):

([param] [, param]) => < statements >param => expression

Имя параметра. Если параметров нет, вместо них нужно поставить (). Если параметров больше одного, их также нужно заключить в ().

Если инструкций несколько, их нужно заключить в <>. Для одного выражения фигурных скобок не требуется, а результат этого выражения будет возвращён функцией (то есть` функция x => 3 + 8 вернёт 11).«`

Конструктор Function

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

Объекты Function можно создавать с помощью оператора new (как и любые другие объекты):

new Function (arg1, arg2, . argN, functionBody)

Ноль или больше имён параметров функции. Имя должно быть строкой, содержащей валидный идентификатор JavaScript. Если параметров несколько, они должны быть разделены запятыми. Например: » x «, » theValue «, или » a,b «.

Инструкции, из которых состоит тело функции.

Конструктор Function можно вызывать и без оператора new, эффект будет тем же.

Параметры функции

Примечание: Остаточные параметры и параметры по умолчанию — это экспериментальная технология, часть спецификации ECMAScript 6, и они пока ещё не получили широкой поддержки среди браузеров.

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

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

Остаточные параметры

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

Объект arguments

Внутри функции получить доступ к её аргументам можно через объект arguments.

  • arguments (en-US): Объект, похожий на массив и содержащий все аргументы, переданные в текущую функцию.
  • arguments.callee (en-US) Устарело : Функция, исполняемая в текущий момент.
  • arguments.caller : Функция, которая вызвала текущую функцию.
  • arguments.length (en-US): Число аргументов, переданных в функцию.

Определение методов

Геттеры и сеттеры

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

Связывает свойство объекта с функцией, которая будет вызвана при обращении к свойству.

Связывает свойство объекта с функцией, которая будет вызвана при попытке изменения свойства.

Синтаксис определения методов

Примечание: Определение методов — это экспериментальная технология, часть спецификации ECMAScript 6, и она пока ещё не получила широкой поддержки среди браузеров.

Начиная с ECMAScript 6, можно определять собственные методы, используют более краткий синтаксис, похожий на геттеры и сеттеры. Более подробно — в статье Определение методов.

var obj =  foo() >, bar() >, >; 

Сравнение конструкторов Function с объявлением функций и функциями-выражениями

Посмотрите на следующие примеры:

Функция, определённая через конструктор Function и приравненная к переменной multiply:

var multiply = new Function("x", "y", "return x * y"); 

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

function multiply(x, y)  return x * y; > 

Анонимная функция-выражение, приравненная к переменной multiply:

var multiply = function (x, y)  return x * y; >; 

Функция-выражение с именем func_name , приравненное к переменной multiply:

var multiply = function func_name(x, y)  return x * y; >; 

Отличия

Во всех случаях результат примерно одинаков, но есть несколько нюансов:

Имя функции и переменная, к которой функция приравнена — это не одно и то же. Имя функции нельзя менять, а вот переменной, к которой приравнена функция, можно дать другое значение. В случае функции-выражения с именем, это имя может быть использовано только внутри самой функции. При попытке использовать его снаружи возникнет ошибка (а если ранее была объявлена переменная с таким именем, будет возвращено undefined ). Например:

var y = function x() >; alert(x); // выкинет ошибку 

Также имя функции-выражения проявляется, если сериализовать функцию через метод Function.toString.

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

Как показано в четвёртом примере, имя функции может отличаться от имени переменной, к которой функция приравнена, эти имена никак не связаны. Объявление функции (function declaration) также создаёт и переменную с именем, аналогичным имени функции. Таким образом:

  1. Если функция определена с помощью функции-выражения (function expression), её имя доступно только внутри самой функции.
  2. Если функция объявлена (function declaration), её имя доступно в той области видимости, где функция была определена.

У функции, определённой с помощью ‘ new Function’ , нет имени. Однако, в JavaScript движке SpiderMonkey, сериализованное представление функции отображается так, как будто оно имеет имя «anonymous». Например, , alert(new Function()) выдаст:

function anonymous() > 

Так как на самом деле у функции нет имени, переменную anonymous нельзя использовать внутри функции. Например, следующий пример выкинет ошибку:

var foo = new Function("alert(anonymous);"); foo(); 

В отличии от функций, определённых через функцию-выражение или конструктор Function , функция, определённая через объявление, может быть использована перед тем, как была определена. Например:

foo(); // выведет FOO! function foo()  alert("FOO!"); > 

Функция, определённая через функцию-выражение, наследует текущую область видимости, то есть создаёт замыкание. А вот функция, созданная с помощью конструктора Function , не наследует ничего, кроме глобальной области видимости (её наследуют вообще все функции).

Функции, определённые через функцию-выражение и объявление функции парсятся только один раз, в отличии от функций, созданных с помощью конструктора. То есть строка, которая передаётся в конструктор Function , парсится при каждом вызове конструктора. И хотя функция-выражение каждый раз создаёт замыкание, тело функции при этом не парсится, и получается, что функции-выражение всё равно быстрее, чем » new Function(. ) «. Поэтому конструктора Function в большинстве случаев стоит избегать, если это возможно.

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

var foo = new Function( "var bar = 'FOO!';\nreturn(function() );", )(); foo(); // "function() " Эта часть строки, составляющей тело функции, не парсится во второй раз. 

Объявление функции можно очень легко (и часто случайно) превратить в функцию-выражение. Объявление функции перестаёт быть таковым, если оно:

  • становится частью выражения
  • не является «исходным элементом» функции или файла. Исходный элемент — это не вложенный элемент внутри функции или скрипта:
var x = 0; // исходный элемент if (x == 0)  // исходный элемент x = 10; // не исходный элемент function boo() > // не исходный элемент > function foo()  // исходный элемент var y = 20; // исходный элемент function bar() > // исходный элемент while (y == 10)  // исходный элемент function blah() > // не исходный элемент y++; // не исходный элемент > > 

Примеры

// объявление функции function foo() > // функция-выражение (function bar() >); // функция-выражение x = function hello() >; if (x)  // функция-выражение function world() > > // объявление функции function a()  // объявление функции function b() > if (0)  // функция-выражение function c() > > > 

Определение функции в зависимости от условия

Функции могут быть определены в зависимости от условий с помощью инструкции function (разрешённое расширение стандарта ECMA-262 Edition 3) или конструктора Function . Обратите внимание, что подобные инструкции запрещены в ES5 strict. Кроме того, эта возможность по-разному ведёт себя в разных браузерах, поэтому не стоит на неё рассчитывать.

В коде ниже функция zero никогда не будет определена и не может быть вызвана, потому что ‘ if (0) ‘ всегда расценивается как false :

if (0)  function zero()  document.writeln("This is zero."); > > 

Если изменить условие на ‘ if (1) ‘, функция zero будет определена.

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

Некоторые JavaScript-движки (но не SpiderMonkey), неверно считают любую функцию-выражение с именем за объявление функции. Это приводит к тому, что функция zero будет определена, даже если условие всегда false . Более безопасный способ определить функцию по условию — это сделать её анонимной и приравнять к переменной:

if (0)  var zero = function ()  document.writeln("This is zero."); >; > 

Примеры

Пример: возврат отформатированного числа

Эта функция возвращает строку, содержащую число с заданным количеством нулей перед ним:

function padZeros(num, totalLen)  var numStr = num.toString(); // Инициализировать возвращаемое значение в виде строки var numZeros = totalLen - numStr.length; // Посчитать число нулей в начале for (var i = 1; i  numZeros; i++)  numStr = "0" + numStr; > return numStr; > 
var result; result = padZeros(42, 4); // возвращает "0042" result = padZeros(42, 2); // возвращает "42" result = padZeros(5, 4); // возвращает "0005" 

Пример: существует ли функция

Можно определить, существует ли функция с помощью оператора typeof . В следующем примере проверяется, есть ли у объекта window функция noFunc . Если есть, то она вызывается; если нет, выполняется какое-то другое действие.

if ("function" == typeof window.noFunc)  // вызывать noFunc() > else  // сделать что-то другое > 

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

Спецификации

Specification
ECMAScript Language Specification
# sec-function-definitions

Поддержка браузерами

BCD tables only load in the browser

Смотрите также

  • Function
  • Инструкция function
  • Оператор function

Found a content problem with this page?

  • Edit the page on GitHub.
  • Report the content issue.
  • View the source on GitHub.

This page was last modified on 4 авг. 2023 г. by MDN contributors.

Your blueprint for a better internet.

MDN

Support

  • Product help
  • Report an issue

Our communities

Developers

  • Web Technologies
  • Learn Web Development
  • MDN Plus
  • Hacks Blog
  • Website Privacy Notice
  • Cookies
  • Legal
  • Community Participation Guidelines

Visit Mozilla Corporation’s not-for-profit parent, the Mozilla Foundation.
Portions of this content are ©1998– 2023 by individual mozilla.org contributors. Content available under a Creative Commons license.

Что такое function в JavaScript?

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

Многие путают функции и методы и не понимают отличий между ними. На самом деле отличий нет, так как что методы, что функции являются одним и тем же. Функции что записаны вне классов называют функциями, а функции что записаны внутри классов называются методами.

Точно такая же ситуация обстоит с переменным. В классах переменные называются полями, а вне классов — переменными.

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

Создание функции

На основе всех данных наша функция будет выглядеть следующим образом:

function test()

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

function test(word)

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

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

function test(some_number)

Функция как тип данных

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

Время чтения: меньше 5 мин

Открыть/закрыть навигацию по статье

  1. Кратко
  2. Как понять
    1. Хранение функции в переменной
    2. Передача функции в вызов другой функции
    3. Возвращение функции как результат вызова
    1. Николай Лопин советует

    Обновлено 20 декабря 2021

    Кратко

    Скопировать ссылку «Кратко» Скопировано

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

    Технически, функция — это объект JavaScript, у которого есть внутренний метод Call ( ) , который добавляет возможность вызова функции.

    Если вы хотите узнать о синтаксисе функций, читайте статью function .

    Как понять

    Скопировать ссылку «Как понять» Скопировано

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

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

    О функции удобно думать как об объекте, который поддерживает операцию вызова.

    Хранение функции в переменной

    Скопировать ссылку «Хранение функции в переменной» Скопировано

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

     const answer = function()  console.log('42!')> answer()// 42! const answer = function()  console.log('42!') > answer() // 42!      

    Можно сохранять в переменную и функцию, объявленную другим способом. При этом оба имени функции будут работать:

     function answerNumber()  console.log('42!')> const answer = answerNumber answerNumber()// 42!answer()// 42! function answerNumber()  console.log('42!') > const answer = answerNumber answerNumber() // 42! answer() // 42!      

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

     const answer = function()  console.log('42!')> const answerNumber = answerconst fn = answer const answer = function()  console.log('42!') > const answerNumber = answer const fn = answer     

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

    Скопировать ссылку «Передача функции в вызов другой функции» Скопировано

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

    Например, функция, которая может выполнить произвольную операцию между двумя числами. Два числа хранятся внутри функции, а операция, которую нужно выполнить, передаётся при вызове:

     function performOperation(operation)  const a = 10 const b = 99 return operation(a, b)> const sum = performOperation(function(one, two) < return one + two >)console.log(sum)// 109 const result = performOperation(function(num1, num2) < return num1 ** (num1 / num2)>)console.log(result)// 1.2618568830660204 function performOperation(operation)  const a = 10 const b = 99 return operation(a, b) > const sum = performOperation(function(one, two)  return one + two >) console.log(sum) // 109 const result = performOperation(function(num1, num2)  return num1 ** (num1 / num2)>) console.log(result) // 1.2618568830660204      

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

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

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

    Другой случай использования — колбэки в асинхронном коде. Иногда необходимо выполнить операцию после того, как закончится какое-то действие. Например, когда пользователь кликнет на кнопку. В этом случае используется метод add Event Listener ( ) , который принимает имя события и колбэк, который нужно вызвать при его наступлении:

     document.getElementsByTagName('button')[0].addEventListener('click', function()  console.log('пользователь кликнул!')>) document.getElementsByTagName('button')[0].addEventListener('click', function()  console.log('пользователь кликнул!') >)      

    Возвращение функции как результат вызова

    Скопировать ссылку «Возвращение функции как результат вызова» Скопировано

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

     function lazySum(a, b)  return function()  return a + b >> function lazySum(a, b)  return function()  return a + b > >      

    Здесь очень легко запутаться во вложенности. При вызове lazy Sum ( ) мы передаём два аргумента. Эти аргументы не используются тут же — мы создаём новую функцию, которая складывает два числа и возвращаем её. После вызова lazy Sum ( ) мы можем сохранить эту функцию в переменную и использовать её, когда нужно:

     const performSum = lazySum(99, 1)console.log(performSum)// function lazySum() console.log(performSum())// 100 const performSum = lazySum(99, 1) console.log(performSum) // function lazySum() console.log(performSum()) // 100      

    Обратите внимание, что значения параметров a и b остаются доступны внутри вложенной функции. Эта особенность связана с контекстом выполнения и лексическим окружением функции. Такой подход также активно используется при разработке на JavaScript.

    На практике

    Скопировать ссылку «На практике» Скопировано

    Николай Лопин советует

    Скопировать ссылку «Николай Лопин советует» Скопировано

    �� Чтобы понять, что в переменной хранится функция, достаточно воспользоваться оператором typeof — для функций он возвращает строку ‘function’ :

     const answer = function()  console.log('42!')> console.log(typeof answer)// 'function' const answer = function()  console.log('42!') > console.log(typeof answer) // 'function'      

    �� Так как функция технически является объектом, то у функции есть свойства и методы. Например, свойство length вернёт количество параметров функции:

     const answer = function()  console.log('42!')> console.log(answer.length)// 0 const sum = function(a, b)  return a + b> console.log(sum.length)// 2 const answer = function()  console.log('42!') > console.log(answer.length) // 0 const sum = function(a, b)  return a + b > console.log(sum.length) // 2      

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

     const calc = function() <> calc.type = 'numbers' console.log(calc.type)// numbers const calc = function() > calc.type = 'numbers' console.log(calc.type) // numbers      

    Функции

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

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

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

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

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

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

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

    function showMessage()

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

    function имя(параметры)

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

    function showMessage() < alert( 'Всем привет!' ); >showMessage(); showMessage();

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

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

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

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

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

    function showMessage() < let message = "Привет, я JavaScript!"; // локальная переменная alert( message ); >showMessage(); // Привет, я JavaScript! alert( message ); // 

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

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

    let userName = 'Вася'; function showMessage() < let message = 'Привет, ' + userName; alert(message); >showMessage(); // Привет, Вася

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

    let userName = 'Вася'; function showMessage() < userName = "Петя"; // (1) изменяем значение внешней переменной let message = 'Привет, ' + userName; alert(message); >alert( userName ); // Вася перед вызовом функции showMessage(); alert( userName ); // Петя, значение внешней переменной было изменено функцией

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

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

    let userName = 'Вася'; function showMessage() < let userName = "Петя"; // объявляем локальную переменную let message = 'Привет, ' + userName; // Петя alert(message); >// функция создаст и будет использовать свою собственную локальную переменную userName showMessage(); alert( userName ); // Вася, не изменилась, функция не трогала внешнюю переменную

    Глобальные переменные

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

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

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

    Параметры

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

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

    function showMessage(from, text) < // параметры: from, text alert(from + ': ' + text); >showMessage('Аня', 'Привет!'); // Аня: Привет! (*) showMessage('Аня', "Как дела?"); // Аня: Как дела? (**)

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

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

    function showMessage(from, text) < from = '*' + from + '*'; // немного украсим "from" alert( from + ': ' + text ); >let from = "Аня"; showMessage(from, "Привет"); // *Аня*: Привет // значение "from" осталось прежним, функция изменила значение локальной переменной alert( from ); // Аня

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

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

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

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

    Значения по умолчанию

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

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

    showMessage("Аня");

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

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

    function showMessage(from, text = "текст не добавлен") < alert( from + ": " + text ); >showMessage("Аня"); // Аня: текст не добавлен

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

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

    function showMessage(from, text = anotherFunction()) < // anotherFunction() выполнится только если не передан text // результатом будет значение text >

    Вычисление параметров по умолчанию

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

    В приведённом выше примере, функция anotherFunction() не будет вызвана вообще, если указан параметр text .

    С другой стороны, функция будет независимо вызываться каждый раз, когда text отсутствует.

    Использование параметров по умолчанию в ранних версиях JavaScript

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

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

    function showMessage(from, text) < if (text === undefined) < text = 'текст не добавлен'; >alert( from + ": " + text ); >

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

    function showMessage(from, text) < // Если значение text ложно, тогда присвоить параметру text значение по умолчанию // заметим, что при этом пустая строка text === "" будет также считаться отсутствующим значением text = text || 'текст не добавлен'; . >

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

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

    Во время выполнения функции мы можем проверить, передан ли параметр, сравнив его с undefined :

    function showMessage(text) < // . if (text === undefined) < // если параметр отсутствует text = 'пустое сообщение'; >alert(text); > showMessage(); // пустое сообщение

    …Или мы можем использовать оператор || :

    function showMessage(text) < // если значение text ложно или равняется undefined, тогда присвоить text значение 'пусто' text = text || 'пусто'; . >

    Современные движки JavaScript поддерживают оператор нулевого слияния ?? . Его использование будет лучшей практикой, в случае, если большинство ложных значений, таких как 0 , следует расценивать как «нормальные».

    function showCount(count) < // если count равен undefined или null, показать "неизвестно" alert(count ?? "неизвестно"); >showCount(0); // 0 showCount(null); // неизвестно showCount(); // неизвестно

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

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

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

    function sum(a, b) < return a + b; >let result = sum(1, 2); alert( result ); // 3

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

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

    function checkAge(age) < if (age >= 18) < return true; >else < return confirm('А родители разрешили?'); >> let age = prompt('Сколько вам лет?', 18); if ( checkAge(age) ) < alert( 'Доступ получен' ); >else

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

    function showMovie(age) < if ( !checkAge(age) ) < return; >alert( "Вам показывается кино" ); // (*) // . >

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

    Результат функции с пустым return или без него – undefined

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

    function doNothing() < /* пусто */ >alert( doNothing() === undefined ); // true

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

    function doNothing() < return; >alert( doNothing() === undefined ); // true

    Никогда не добавляйте перевод строки между return и его значением

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

    return (some + long + expression + or + whatever * f(a) + f(b))

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

    return; (some + long + expression + or + whatever * f(a) + f(b))

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

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

    return ( some + long + expression + or + whatever * f(a) + f(b) )

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

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

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

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

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

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

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

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

    showMessage(..) // показывает сообщение getAge(..) // возвращает возраст (получая его каким-то образом) calcSum(..) // вычисляет сумму и возвращает результат createForm(..) // создаёт форму (и обычно возвращает её) checkPermission(..) // проверяет доступ, возвращая true/false

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

    Одна функция – одно действие

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

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

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

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

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

    Сверхкороткие имена функций

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

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

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

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

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

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

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

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

    function showPrimes(n) < nextPrime: for (let i = 2; i < n; i++) < for (let j = 2; j < i; j++) < if (i % j == 0) continue nextPrime; >alert( i ); // простое > >

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

    function showPrimes(n) < for (let i = 2; i < n; i++) < if (!isPrime(i)) continue; alert(i); // простое >> function isPrime(n) < for (let i = 2; i < n; i++) < if ( n % i == 0) return false; >return true; >

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

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

    Итого

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

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

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

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

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

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

    Задачи

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

    важность: 4

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

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

    function checkAge(age) < if (age >18) < return true; >else < // . return confirm('Родители разрешили?'); >>

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

    function checkAge(age) < if (age >18) < return true; >// . return confirm('Родители разрешили?'); >

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

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

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

    важность: 4

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

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

    function checkAge(age) < if (age >18) < return true; >else < return confirm('Родители разрешили?'); >>

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

    Сделайте два варианта функции checkAge :

    1. Используя оператор ?
    2. Используя оператор ||
    function checkAge(age) < return (age >18) ? true : confirm('Родители разрешили?'); >

    Используя оператор || (самый короткий вариант):

    function checkAge(age) < return (age >18) || confirm('Родители разрешили?'); >

    Обратите внимание, что круглые скобки вокруг age > 18 не обязательны. Они здесь для лучшей читаемости кода.

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

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