---
title: Функции
slug: Web/JavaScript/Reference/Functions
tags:
  - Функции
  - Функция
translation_of: Web/JavaScript/Reference/Functions
---
<div>{{jsSidebar("Functions")}}</div>

<h2 id="Summary" name="Summary">Сводка</h2>

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

<p>В JavaScript функции являются объектами первого класса, то есть: они являются объектами и с ними можно взаимодействовать и передавать их точно так же как любой другой объект. Если быть точным, функции — это объекты <code><a href="ru/docs/Web/JavaScript/Reference/Global_Objects/Function">Function</a></code>.</p>

<p>Больше подробностей и примеров можно найти в <a href="/ru/docs/Web/JavaScript/Guide/Functions">руководстве по функциям в JavaScript</a>.</p>

<h2 id="Описание">Описание</h2>

<p>Каждая функция в JavaScript — это объект Function.  О свойствах и методах объектов Function можно прочитать в статье {{jsxref("Function")}}.</p>

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

<p>Чтобы вернуть значение, отличное от значения по умолчанию, в функции должна быть инструкция <code><a href="/ru/docs/Web/JavaScript/Reference/Statements/return">return</a></code>, которая указывает, что именно нужно вернуть. Функция без него вернёт значение по умолчанию. В случае <a href="/ru/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor">конструктора</a>, вызванного с ключевым словом <code><a href="/ru/docs/Web/JavaScript/Reference/Operators/new">new</a>, </code>значение по умолчанию — это значение его параметра <code>this</code>. Для остальных функций значением по умолчанию будет <code>undefined</code>.</p>

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

<pre class="brush: 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);
</pre>

<p><a href="/ru/docs/Web/JavaScript/Reference/Operators/this"><code>Ключевое слово this</code></a> не ссылается на функцию, которая выполняется в данный момент, поэтому вы должны обращаться к объектами Function по имени, даже внутри тела самой функции.</p>

<h2 id="Defining_functions" name="Defining_functions">Определение функций</h2>

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

<h3 id="The_function_declaration_.28function_statement.29" name="The_function_declaration_.28function_statement.29">Объявление функции (инструкция <code>function</code>)</h3>

<p>Специальный синтаксис для объявления функций (более подробно: <a href="/ru/docs/Web/JavaScript/Reference/Statements/function">function statement</a>):</p>

<pre>function <em>name</em>([<em>param</em>[, <em>param</em>[, ... <em>param</em>]]]) {
   <em>statements</em>
}
</pre>

<dl>
 <dt><code>name</code></dt>
 <dd>Имя функции.</dd>
</dl>

<dl>
 <dt><code>param</code></dt>
 <dd>Имя аргумента, передаваемого в функцию. У функции может быть не более 255 аргументов.</dd>
</dl>

<dl>
 <dt><code>statements</code></dt>
 <dd>Инструкции, из которых состоит тело функции.</dd>
</dl>

<h3 id="The_function_expression_.28function_operator.29" name="The_function_expression_.28function_operator.29">Функция-выражение (оператор <code>function</code>)</h3>

<p>Функция-выражение похожа на определение функции и имеет такой же синтаксис (более подробно: <a href="/ru/docs/Web/JavaScript/Reference/Operators/function">function operator</a>):</p>

<pre>function [<em>name</em>]([<em>param</em>] [, <em>param</em>] [..., <em>param</em>]) {
   <em>statements</em>
}
</pre>

<dl>
 <dt><code>name</code></dt>
 <dd>Имя функции. Может быть не указано, в таком случае функция становится анонимной.</dd>
</dl>

<dl>
 <dt><code>param</code></dt>
 <dd>Имя аргумента, передаваемого в функцию. У функции может быть не более 255 аргументов.</dd>
 <dt><code>statements</code></dt>
 <dd>Инструкции, из которых состоит тело функции.</dd>
</dl>

<h3 id="Стрелочная_функция-выражение_(>)">Стрелочная функция-выражение (=&gt;)</h3>

<div class="note">
<p><strong>Заметка:</strong> стрелочные функции являются экспериментальной технологией<em>,</em> частью спецификации ECMAScript 6 и пока что не поддерживаются всеми браузерами.</p>
</div>

<p>Стрелочные функции отличаются более кратким синтаксисом и тем, что они лексически связывают значение своего <code>this (подробнее об этом в статье <a href="/ru/docs/Web/JavaScript/Reference/Functions/Arrow_functions">Стрелочные функции</a>):</code></p>

<pre>([param] [, param]) =&gt; {
   statements
}

param =&gt; expression
</pre>

<dl>
 <dt><code>param</code></dt>
 <dd>Имя параметра. Если параметров нет, вместо них нужно поставить (). Если параметров больше одного, их также нужно заключить в ().</dd>
 <dt><code>statements or expression</code></dt>
 <dd>Если инструкций несколько, их нужно заключить в {}. Для одного выражения фигурных скобок не требуется, а результат этого выражения будет возвращён функцией (то есть<code> функция x =&gt; 3 + 8 вернёт 11).</code><code> </code></dd>
</dl>

<h3 id="The_Function_constructor" name="The_Function_constructor">Конструктор <code>Function</code></h3>

<div class="note">
<p><strong>Заметка:</strong> Использовать конструктор Function не рекомендуется, так как он принимает тело функции в виде строки, а это может помешать оптимизациям, которые выполняют движки JavaScript, а также привести к другим проблемам.</p>
</div>

<p>Объекты {{jsxref("Function")}} можно создавать с помощью оператора <code>new </code>(как и любые другие объекты):</p>

<pre>new Function (<em>arg1</em>, <em>arg2</em>, ... <em>argN</em>, <em>functionBody</em>)
</pre>

<dl>
 <dt><code>arg1, arg2, ... arg<em>N</em></code></dt>
 <dd>Ноль или больше имён параметров функции. Имя должно быть строкой, содержащей валидный идентификатор JavaScript. Если параметров несколько, они должны быть разделены запятыми. Например: "<code>x</code>", "<code>theValue</code>", или "<code>a,b</code>".</dd>
</dl>

<dl>
 <dt><code>functionBody</code></dt>
 <dd>Инструкции, из которых состоит тело функции.</dd>
</dl>

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

<h2 id="Параметры_функции">Параметры функции</h2>

<div class="note">
<p><strong>Примечание:</strong> Оставшиеся параметры и параметры по умолчанию <em>— это экспериментальная </em>технология, часть спецификации ECMAScript 6, и они пока ещё не получили широкой поддержки среди браузеров.</p>
</div>

<h3 id="Параметры_по_умолчанию">Параметры по умолчанию</h3>

<p>Параметры функции по умолчанию позволяют инициализировать формальные параметры со значениями по умолчанию, если им не было передано значение, или было передано <code>undefined</code>. Подробнее о них можно узнать в статье <a href="/ru/docs/Web/JavaScript/Reference/Functions/Default_parameters">Параметры по умолчанию</a>.</p>

<h3 id="Оставшиеся_параметры">Оставшиеся параметры</h3>

<p>Синтаксис оставшихся параметров позволяет передать бесконечное число аргументов как массив. Подробности можно найти в статье <a href="/ru/docs/Web/JavaScript/Reference/Functions/rest_parameters">Оставшиеся параметры</a>.</p>

<h2 id="The_arguments_object" name="The_arguments_object">Объект <code>arguments</code></h2>

<p>Внутри функции получить доступ к её аргументам можно через объект <a href="/ru/docs/Web/JavaScript/Reference/Functions/arguments">arguments</a>.</p>

<ul>
 <li><code><a href="/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments">arguments</a></code>: Объект, похожий на массив и содержащий все аргументы, переданные в текущую функцию.</li>
 <li><code><a href="/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments/callee">arguments.callee</a></code> {{Deprecated_inline}}: Функция, исполняемая в текущий момент.</li>
 <li><code><a href="/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments/caller">arguments.caller</a></code> {{Obsolete_inline}} : Функция, которая вызвала текущую функцию.</li>
 <li><code><a href="/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments/length">arguments.length</a></code>: Число аргументов, переданных в функцию.</li>
</ul>

<h2 id="Определение_методов">Определение методов</h2>

<h3 id="Геттеры_и_сеттеры">Геттеры и сеттеры</h3>

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

<dl>
 <dt><a href="/en-US/docs/Web/JavaScript/Reference/Functions/get">get</a></dt>
 <dd>Связывает свойство объекта с функцией, которая будет вызвана при обращении к свойству.</dd>
 <dt><a href="/en-US/docs/Web/JavaScript/Reference/Functions/set">set</a></dt>
 <dd>Связывает свойство объекта с функцией, которая будет вызвана при попытке изменения свойства.</dd>
</dl>

<h3 id="Синтаксис_определения_методов">Синтаксис определения методов</h3>

<div class="note">
<p><strong>Примечание:</strong> <em>Определение методов — это экспериментальная </em>технология, часть спецификации ECMAScript 6, и она пока ещё не получила широкой поддержки среди браузеров.</p>
</div>

<p>Начиная с ECMAScript 6, можно определять собственные методы, используют более краткий синтаксис, похожий на геттеры и сеттеры. Более подробно  — в статье <a href="/ru/docs/Web/JavaScript/Reference/Functions/Method_definitions">Определение методов.</a></p>

<pre class="brush: js">var obj = {
  foo() {},
  bar() {}
};</pre>

<h2 id="Function_constructor_vs._function_declaration_vs._function_expression" name="Function_constructor_vs._function_declaration_vs._function_expression">Сравнение конструкторов <code>Function</code> с объявлением функций и функциями-выражениями</h2>

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

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

<pre class="brush: js">var multiply = new Function("x", "y", "return x * y");</pre>

<p>Объявление функции multiply:</p>

<pre class="brush: js">function multiply(x, y) {
   return x * y;
}
</pre>

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

<pre class="brush: js">var multiply = function(x, y) {
   return x * y;
};
</pre>

<p><em>Функция-выражение</em> с именем <code>func_name</code>, приравненное к переменной<code> multiply:</code></p>

<pre class="brush: js">var multiply = function func_name(x, y) {
   return x * y;
};
</pre>

<h3 id="Отличия">Отличия</h3>

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

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

<pre class="brush: js">var y = function x() {};
alert(x); // выкинет ошибку
</pre>

<p>Также имя функции-выражения проявляется, если сериализовать функцию через метод <a href="/ru/docs/Web/JavaScript/Reference/Global_Objects/Function/toString">Function.toString.</a></p>

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

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

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

<p>У функции, определённой с помощью '<code>new Function'</code>, нет имени.  Однако, в JavaScript движке <a href="/en-US/docs/Mozilla/Projects/SpiderMonkey">SpiderMonkey</a>, сериализованное представление функции отображается так, как будто оно имеет имя "anonymous". Например, , <code>alert(new Function())</code> выдаст:</p>

<pre class="brush: js">function anonymous() {
}
</pre>

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

<pre class="brush: js">var foo = new Function("alert(anonymous);");
foo();
</pre>

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

<pre class="brush: js">foo(); // выведет FOO!
function foo() {
   alert('FOO!');
}
</pre>

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

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

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

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

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

<ul>
 <li>становится частью выражения</li>
 <li>не является "исходным элементом" функции или файла. Исходный элемент  - это не вложенный элемент внутри функции или скрипта:</li>
</ul>

<pre class="brush: js">var x = 0;               // исходный элемент
if (x == 0) {            // исходный элемент
   x = 10;               // не исходный элемент
   function boo() {}     // не исходный элемент
}
function foo() {         // исходный элемент
   var y = 20;           // исходный элемент
   function bar() {}     // исходный элемент
   while (y == 10) {     // исходный элемент
      function blah() {} // не исходный элемент
      y++;               // не исходный элемент
   }
}
</pre>

<h3 id="Примеры">Примеры</h3>

<pre class="brush: js">// объявление функции
function foo() {}

// функция-выражение
(function bar() {})

// функция-выражение
x = function hello() {}


if (x) {
   // функция-выражение
   function world() {}
}


// объявление функции
function a() {
   // обявление функции
   function b() {}
   if (0) {
      // функция-выражение
      function c() {}
   }
}
</pre>

<h2 id="Conditionally_defining_a_function" name="Conditionally_defining_a_function">Определение функции в зависимости от условия</h2>

<p>Функции могут быть определены в зависимости от условий с помощью инструкции <code>function (разрешённое расширение стандарта</code> <a href="http://www.ecma-international.org/publications/standards/Ecma-262.htm">ECMA-262 Edition 3</a>) или конструктора <code>Function</code>. Обратите внимание, что подобные инструкции <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=609832">запрещены в ES5 strict</a>. Кроме того, эта возможность по-разному ведёт себя в разных браузерах, поэтому не стоит на неё рассчитывать.</p>

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

<pre class="brush: js">if (0) {
   function zero() {
      document.writeln("This is zero.");
   }
}
</pre>

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

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

<p>Некоторые JavaScript-движки (но не <a href="/en-US/docs/SpiderMonkey">SpiderMonkey</a>), неверно считают любую функцию-выражение с именем за объявление функции. Это приводит к тому, что функция <code>zero</code> будет определена, даже если условие всегда <code>false</code>. Более безопасный способ определить функцию по условию - это сделать её анонимной и приравнять к переменной:</p>

<pre class="brush: js">if (0) {
   var zero = function() {
      document.writeln("This is zero.");
   }
}
</pre>

<h2 id="Examples" name="Examples">Примеры</h2>

<h3 id="Example:_Returning_a_formatted_number" name="Example:_Returning_a_formatted_number">Пример: возврат отформатированного числа</h3>

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

<pre class="brush: js">function padZeros(num, totalLen) {
   var numStr = num.toString();             // Инициализировать возвращаемое значение в виде строки
   var numZeros = totalLen - numStr.length; // Посчитать число нулей в начале
   for (var i = 1; i &lt;= numZeros; i++) {
      numStr = "0" + numStr;
   }
   return numStr;
}
</pre>

<p>Вызовем <code>padZeros</code>:</p>

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

<h3 id="Example:_Determining_whether_a_function_exists" name="Example:_Determining_whether_a_function_exists">Пример: существует ли функция</h3>

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

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

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

<h2 id="Спецификации">Спецификации</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">Спецификация</th>
   <th scope="col">Статус</th>
   <th scope="col">Комментарий</th>
  </tr>
  <tr>
   <td>ECMAScript 1st Edition.</td>
   <td>Стандарт</td>
   <td>Изначальное определение. Релизовано в JavaScript 1.0</td>
  </tr>
  <tr>
   <td>{{SpecName('ES5.1', '#sec-13', 'Function Definition')}}</td>
   <td>{{Spec2('ES5.1')}}</td>
   <td> </td>
  </tr>
  <tr>
   <td>{{SpecName('ES6', '#sec-function-definitions', 'Function definitions')}}</td>
   <td>{{Spec2('ES6')}}</td>
   <td>Новое: стрелочные функции, генераторы, параметры по умолчанию, оставшиеся параметры</td>
  </tr>
 </tbody>
</table>

<h2 id="Поддержка_браузерами">Поддержка браузерами</h2>

<p>{{ CompatibilityTable() }}</p>

<div id="compat-desktop">
<table class="compat-table">
 <tbody>
  <tr>
   <th>Feature</th>
   <th>Chrome</th>
   <th>Firefox (Gecko)</th>
   <th>Internet Explorer</th>
   <th>Opera</th>
   <th>Safari</th>
  </tr>
  <tr>
   <td>Начальная поддержка</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
  </tr>
 </tbody>
</table>
</div>

<div id="compat-mobile">
<table class="compat-table">
 <tbody>
  <tr>
   <th>Feature</th>
   <th>Android</th>
   <th>Chrome for Android</th>
   <th>Firefox Mobile (Gecko)</th>
   <th>IE Mobile</th>
   <th>Opera Mobile</th>
   <th>Safari Mobile</th>
  </tr>
  <tr>
   <td>Начальная поддержка</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
  </tr>
 </tbody>
</table>
</div>

<h2 id="See_also" name="See_also">См. также</h2>

<ul>
 <li><a href="https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Function"><code>Function</code></a></li>
 <li><a href="https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Statements/function">Инструкция<code> function</code></a></li>
 <li><a href="https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Operators/function">Оператор<code> function</code></a></li>
</ul>