- Операторы
- Управляющие инструкции
- JS Объекты
- Array
- Boolean
- Date
- Error
- Function
- Global
- JSON
- Math
- Number
- Object
- RegExp
- String
- Unicode
- 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.