Movatterモバイル変換


[0]ホーム

URL:


MDN Web Docs

Эта страница была переведена с английского языка силами сообщества. Вы тоже можете внести свой вклад, присоединившись к русскоязычному сообществу MDN Web Docs.

Функции

BaselineWidely available *

Сводка

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

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

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

Описание

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

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

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

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

js
/* Объявляем функцию '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]]]) {   statements}
name

Имя функции.

param

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

statements

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

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

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

function [name]([param] [, param] [..., param]) {   statements}
name

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

param

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

statements

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

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

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

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

([param] [, param]) => {   statements}param => expression
param

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

statements or expression

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

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

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

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

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

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

functionBody

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

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

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

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

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

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

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

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

Объектarguments

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

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

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

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

get

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

set

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

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

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

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

js
var obj = {  foo() {},  bar() {},};

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

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

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

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

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

js
function multiply(x, y) {  return x * y;}

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

js
var multiply = function (x, y) {  return x * y;};

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

js
var multiply = function func_name(x, y) {  return x * y;};

Отличия

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

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

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

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

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

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

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

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

js
function anonymous() {}

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

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

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

js
foo(); // выведет FOO!function foo() {  alert("FOO!");}

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

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

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

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

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

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

Примеры

js
// объявление функции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:

js
if (0) {  function zero() {    document.writeln("This is zero.");  }}

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

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

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

js
if (0) {  var zero = function () {    document.writeln("This is zero.");  };}

Примеры

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

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

js
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;}

ВызовемpadZeros:

js
var result;result = padZeros(42, 4); // возвращает "0042"result = padZeros(42, 2); // возвращает "42"result = padZeros(5, 4); // возвращает "0005"

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

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

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

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

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

Specification
ECMAScript® 2026 Language Specification
# sec-function-definitions

Совместимость с браузерами

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

Help improve MDN

Learn how to contribute.

This page was last modified on byMDN contributors.


[8]ページ先頭

©2009-2025 Movatter.jp