- Операторы
- Управляющие инструкции
- JS Объекты
- Array
- Boolean
- Date
- Error
- Function
- Global
- JSON
- Math
- Number
- Object
- RegExp
- String
- Symbol
- Итераторы и генераторы
- Map и WeakMap
- Set и WeakSet
- Локализация
- браузер BOM
- HTML DOM
- События
- HTML Объекты
- Промисы, async/await
- Сетевые запросы
- Бинарные данные и файлы
- Разное
Объект Function
В JavaScript функция тоже является объектом - объектом Function и тоже имеет прототип, свойства, методы. Все функции, которые используются в программе, являются объектами Function и имеют все его свойства и методы.
Синтаксис
new Function ([arg1[, arg2[, ... argN]],] functionBody)
Параметры
- arg1, arg2, ... argN
Имена параметров для создаваемой функции. Каждый аргумент должен быть строкой, которая является корректным идентификатором javascript или списком таких строк, разделенных запятой. Например: "x", "theValue" или "a,b".- functionBody
- javascript-код тела функции
Описание, комментарии, примеры
Каждая функция в JavaScriptт является объектом класса Function.
Все аргументы, переданные функции, интерпретируются как имена параметров для создаваемой функции, в порядке их перечисления.
Вызов конструктора Function как функции работает так же, как вызов с new
. Иначе говоря, оператор new
при вызове Function необязателен.
Пример создания функции
var multiply = new Function("x", "y", "return x * y") // или так: var multiply = new Function("x,y", "return x * y") var theAnswer = multiply(7, 6);
Свойства
- length
- Специфицирует количество аргументов, ожидаемое функцией.
Методы
- apply
- Даёт возможность применять метод другого объекта в контексте вызывающего объекта.
- bind
- создаёт новую функцию, которая при вызове устанавливает в качестве контекста выполнения
this
предоставленное значение. - call
- Позволяет вызывать (выполнять) метод другого объекта в контексте вызывающего объекта
length
Свойство length определяет количество аргументов, ожидаемых функцией.
Комментарии
Свойство length
относится к определению функции и указывает количество объявленных в определении аргументов.
Для получения аргументов, реально переданных функции, внутри тела функции можно использовать псевдо-массив arguments и его свойство length
apply
Даёт возможность применить метод другого объекта в контексте вызывающего объекта.
Синтаксис
function.apply(thisArg[, argsArray]);
Параметры
- thisArg
- Задает значение
this
внутри функции.
ЕслиthisArg
-null
илиundefined
, то это будет глобальный объект.
В ином случае,this
будет равноObject(thisArg)
(то естьthisArg
, еслиthisArg
уже объект, илиString, Boolean
илиNumber
, еслиthisArg
- примитивное значение соответствующего типа). Таким образом, при выполнении функции всегда соблюдается условиеtypeof this
== 'object'. - argsArray
- Массив аргументов, с которыми будет вызвана функция, или
null/undefined
для вызова без аргументов.
Комментарии
Любую функцию в JavaScript можно вызвать в контексте любого объекта.
Используя apply
, вы можете вызывать одну функцию в контексте множества различных объектов.
Метод apply
очень похож на call, за исключением передачи аргументов. В apply
используется массив аргументов вместо списка именованных параметров.
Используя apply
, вы можете использовать литеральное объявление массива, например:
fun.apply(this, [name, value])
Вы также можете использовать в качестве параметра argArray
. Это избавляет от необходимости знать, с какими параметрами была вызвана исходная функция.
bind
Метод bind() создаёт новую функцию, которая при вызове устанавливает в качестве контекста выполнения this
предоставленное значение. В метод также передаётся набор аргументов, которые будут установлены перед переданными в привязанную функцию аргументами при её вызове.
Синтаксис
function.bind(thisArg[, arg1[, arg2[, ...]]])
Параметры
- thisArg
- Значение, передаваемое в качестве
this
в целевую функцию при вызове привязанной функции. Значение игнорируется, если привязанная функция конструируется с помощью оператораnew
. - arg1, arg2 ..
- Аргументы, с которыми будет вызвана функция.
Примеры
let obj = { // инициализируем переменную, содержащую объект a: 100, b: 200 }; // функция возвращает сумму трех значений let func = function( c ) { return this.a + this.b + c }; // переменная содержит новую функцию, которая вызывается как метод объекта let newFunc = func.bind( obj, 300 ); newFunc(); // возвращаемое значение 600
В следующем примере мы создадим новую функцию путём фиксирования аргументов существующей (частичное применение), этот прием в функциональном программировании называется каррингом (currying):
// функция возвращает произведение 2 аргументов let multiply = function( a,b ) { return a * b }; // создаем новую функцию, подобную multiply, но с контекстом равным null и первым аргументом равным 3 let triple = multiply.bind( null, 3 ); // новая функция принимает один аргумент triple(2) // 6 (первый аргумент связан со значением 3, а значение 2 передается в качестве второго аргумента) triple(3) // 9 (первый аргумент связан со значением 3, а значение 3 передается в качестве второго аргумента) triple(4) // 12 (первый аргумент связан со значением 3, а значение 4 передается в качестве второго аргумента)
call
Позволяет вызывать (выполнять) метод другого объекта в контексте данного (вызывающего) объекта.
Синтаксис
function.call(thisArg[, arg1[, arg2[, ...]]])
Параметры
- thisArg
- Задает значение
this
внутри функции. ЕслиthisArg
-null
илиundefined
, то это будет глобальный объект. В ином случае,this
будет равноObject(thisArg)
(то естьthisArg
, еслиthisArg
уже объект, илиString, Boolean
илиNumber
, еслиthisArg
- примитивное значение соответствующего типа). Таким образом, при выполнении функции всегда соблюдается условиеtypeof this
== 'object'. - arg1, arg2 ..
- Аргументы, с которыми будет вызвана функция.
Комментарии
Метод call
может применяться для вызова функции в контексте нужного объекта.
Примеры
Вызов sayName в контексте разных объектов
var Animal1 = {name: 'Cat'} var Animal2 = {name: 'Dog'} function sayName() { // this — ссылка на объект, в контексте которого вызвана функция alert(this.name); } sayName.call(Animal1) // выдаст сообщение "Cat" sayName.call(Animal2) // выдаст сообщение "Dog"
При этом совершенно не важно, какому объекту принадлежит функция. В качестве текущего(this
) объекта будет взят первый аргумент.
var Animal1 = { name: 'Cat', sayName: function() { alert(this.name); } }; var Animal2 = {name: 'Dog'}; Animal1.sayName() // выдаст сообщение "Cat" Animal1.sayName.call(Animal2) // выдаст сообщение "Dog"
Помимо смены контекста вызова, метод call может передавать в функцию аргументы:
var obj = {attr: 10}; function sum(a, b) { alert(this.attr + a + b); } sum.call(obj, 5, 2) // выдаст сообщение с результатом "17"
var str = ''; function callMe(arg1, arg2){ var s = ""; s += "this value: " + this; s += "\n"; for (i in callMe.arguments) { s += "arguments: " + callMe.arguments[i]; s += "\n"; } return s; } str += "Original function: \n"; str += callMe(1, 2) + '\n'; str += "Function called with call:\n"; str += callMe.call(3, 4, 5); alert (str); /* Output: Original function: this value: [object Window] arguments: 1 arguments: 2 Function called with call: this value: 3 arguments: 4 arguments: 5 */
arguments
Переменная, доступная внутри функции и содержащая аргументы и ссылку на саму функцию.
Описание, комментарии, примеры
Локальная переменная arguments доступна внутри функций.
Вы можете обращаться к аргументу по номеру, начиная от 0. При этом arguments содержит не объявленные, а реально переданные аргументы.
Следующий пример выведет реально переданные три аргумента, несмотря на то, что в функции их всего два.
function func(a,b) { alert(arguments[0] + '\n '+ arguments[1] + '\n '+ arguments[2]) } func(1,2,3)
Кроме цифровых индексов, у arguments есть свойство length
, такое же как у массива.
Благодаря этому можно вызывать функции с переменным числом параметров. В следующем примере функция возвращает сумму всех аргументов.
Пример: сумма аргументов
function sum() { var s = 0; for(var i=0; i < arguments.length; i++) s += arguments[i]; return s; } alert ( sum (1,2,3,4,5,6,7,8,9) );
Несмотря на доступ по индексу и наличие свойства length
, arguments не является массивом, т.е не принадлежит типу Array
.
Поэтому для arguments нельзя напрямую вызвать методы этого класса:
arguments.pop() // ошибка !
Можно, однако, вызвать методы Array через apply/call:
var args = Array.prototype.slice.call(arguments)
Ссылка на функцию arguments.callee
Кроме аргументов, arguments содержит ссылку на выполняющуюся функцию.
Ее можно использовать для задания и чтения статических свойств.
В следующем примере для этого используется статическое свойство called
.
Пример: подсчет количества выполнений
function func() { arguments.callee.called++ } func.called = 0; func() func() alert(func.called) // 2
Значения по умолчанию
Если при вызове функции аргумент не был указан, то его значением становится undefined
.
Параметрам функции можно присвоить дефолтное значение. Оно будет использоваться, когда при вызове функции этому параметру не будет задано значение с помощью аргумента:
ex_1: ex_2:
function setBgColor(selector, color = 'green') { const el = document.querySelector(selector); el.style.backgroundColor = color; } setBgColor('#ex_1'); setBgColor('#ex_2', '#00aabb');
При вызове функции с одним аргументом, второму параметру будет автоматически присвоено строка 'green'
.
Работу параметра по умолчанию можно представить так:
function setBgColor(selector,color) { const el = document.querySelector(selector); color = color === undefined ? 'green' : color el.style.backgroundColor = color; } setBgColor('#ex_2'); setBgColor('#ex_1', '#00aabb');
Остаточные параметры (...)
Остаточные параметры могут быть обозначены через три точки ....
Буквально это значит: «собери оставшиеся параметры и положи их в массив».
Например, соберём все аргументы в массив args:
function sumAll(...args) { // args — имя массива let sum = 0; for (let arg of args) sum += arg; return sum; } alert( sumAll(1) ); // 1 alert( sumAll(1, 2) ); // 3 alert( sumAll(1, 2, 3) ); // 6Можно положить первые несколько параметров в переменные, а остальные – собрать в массив. В примере ниже первые два аргумента функции станут именем и фамилией, а третий и последующие превратятся в массив titles:
function showName(firstName, lastName, ...titles) { alert( firstName + ' ' + lastName ); // Юлий Цезарь // Оставшиеся параметры пойдут в массив titles = ["Консул", "Император"] alert( titles[0] ); // Консул alert( titles[1] ); // Император alert( titles.length ); // 2 } showName("Юлий", "Цезарь", "Консул", "Император");
Остаточные параметры должны располагаться в конце
Оператор расширения
Оператор расширения позволяет расширять выражения в тех местах, где предусмотрено использование нескольких аргументов (при вызовах функции) или ожидается несколько элементов (для массивов).
Давайте разберем, что это означает и чем нам может пригодится.
Пример 1 — вставка массивов в массив
В приведенном примере мы не используем оператор расширения и хотим поместить субмассив в начальный массив.
let mid = [3, 4]; let arr = [1, 2, mid, 5, 6];
Мы создали массив mid
. Затем мы создали новый массив, который поместили в массив mid. Если выполнить этот код, мы получим:
1, 2, [3, 4], 5, 6]
И это не то, что мы хотели получить. Мы хотели получить цифры от 1 до 6. И тут нам поможет оператор расширения!
const mid = [3, 4]; let arr = [1, 2, ...mid, 5, 6]; alert(arr);
А вот в этом случае мы как раз и получим [1, 2, 3, 4, 5, 6].
Создавая массив arr
и используя … при вставке субмассива, наш массив mid
расширяется. Это расширение означает, что каждый элемент массива mid
помещается внутрь arr
.
Пример 2
let arr1 = [1, -2, 3, 4]; let arr2 = [8, 3, -8, 1]; alert( Math.max(1, ...arr1, 2, ...arr2, 25) ); // 25 let str = "Привет"; alert( [...str] ); // П,р,и,в,е,т
Функции-стрелки
Существует ещё более простой и краткий синтаксис для создания функций, который часто лучше, чем синтаксис Function Expression.
Он называется «функции-стрелки» или «стрелочные функции» (arrow functions), т.к. выглядит следующим образом:
let func = (arg1, arg2, ...argN) => expression
…Такой код создаёт функцию func
с аргументами arg1..argN
и вычисляет expression
с правой стороны с их использованием, возвращая результат.
Другими словами, это более короткий вариант такой записи:
let func = function(arg1, arg2, ...argN) { return expression; };
Давайте взглянем на конкретный пример:
let sum = (a, b) => a + b; /* Более короткая форма для: let sum = function(a, b) { return a + b; }; */ alert( sum(1, 2) ); // 3
То есть, (a, b) => a + b
задаёт функцию с двумя аргументами a
и b
, которая при запуске вычисляет выражение справа a + b
и возвращает его результат.
-
Если у нас только один аргумент, то круглые скобки вокруг параметров можно опустить, сделав запись ещё короче:
// тоже что и // let double = function(n) { return n * 2 } let double = n => n * 2; alert( double(3) ); // 6
-
Если нет аргументов, указываются пустые круглые скобки:
let sayHi = () => alert("Hello!"); sayHi();
Функции-стрелки могут быть использованы так же, как и Function Expression.
Например, для динамического создания функции:
let age = prompt("Сколько Вам лет?", 18); let welcome = (age < 18) ? () => alert('Привет') : () => alert("Здравствуйте!"); welcome(); // теперь всё в порядке
Поначалу функции-стрелки могут показаться необычными и трудночитаемыми, но это быстро пройдёт, как только глаза привыкнут к этим конструкциям.
Они очень удобны для простых однострочных действий, когда лень писать много букв.
Стрелочные функции – это не просто «сокращение», чтобы меньше писать. У них есть ряд других полезных особенностей.
При написании JavaScript-кода часто возникают ситуации, когда нам нужно написать небольшую функцию, которая будет выполнена где-то ещё.
Например:
arr.forEach(func)
–func
выполняетсяforEach
для каждого элемента массива.setTimeout(func)
–func
выполняется встроенным планировщиком.- …и так далее.
Это очень в духе JavaScript – создать функцию и передать её куда-нибудь.
И в таких функциях мы обычно не хотим выходить из текущего контекста. Здесь как раз и полезны стрелочные функци
Многострочные стрелочные функции
В примерах выше аргументы использовались слева от =>
, а справа вычислялось выражение с их значениями.
Порой нам нужно что-то посложнее, например, выполнить несколько инструкций. Это также возможно, нужно лишь заключить инструкции в фигурные скобки. И использовать return
внутри них, как в обычной функции.
Например:
let sum = (a, b) => { // фигурная скобка, открывающая тело многострочной функции let result = a + b; return result; // при фигурных скобках для возврата значения нужно явно вызвать return }; alert( sum(1, 2) ); // 3
Стрелочные функции:
- Без фигурных скобок:
(...args) => expression
– правая сторона выражение: функция выполняет его и возвращает результат. - С фигурными скобками:
(...args) => { body }
– скобки позволяют нам писать многострочные инструкции внутри функции, но при этом необходимо указывать директивуreturn
, чтобы вернуть какое-либо значение. - Не имеют
this
. - Не имеют
arguments
. - Не могут быть вызваны с
new
.