Function: подробно о функциях в JavaScript

В этом руководстве вы узнаете о типе Function, который является типом всех функций в JavaScript.

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

Свойства функций

У каждой функции есть два важных свойства: length и prototype.

  • Свойство length определяет количество именованных аргументов, указанных в объявлении функции.
  • Свойство prototype ссылается на фактический объект функции.

Следующий пример:

function add(x, y) {
    return x + y;
}
console.log(add.length); // 2 
console.log(add.prototype); // Object{}

Функция add() принимает два аргумента x и y. Следовательно, свойство length возвращает 2.

new.target

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

let result = add(10,20); 
console.log(result); // 30

Кроме того, вы можете вызвать функцию с ключевым словом new в качестве конструктора:

let obj = new add(10,20);

В ES6 появилось псевдосвойство new.target, которое позволяет определить, была ли функция или конструктор вызвана с помощью оператора new.

Если функция вызывается нормально, new.target не undefined. Однако, если функция вызывается с использованием ключевого слова new в качестве конструктора, new.target возвращает ссылку на конструктор.

Например:

function add(x, y) {
    console.log(new.target);
    return x + y;
}
let result = add(10, 20);
let obj = new add(10, 20);

Выход:

undefined 
[Function: add]

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

Например, чтобы предотвратить вызов функции add() с ключевым словом new в качестве конструктора, вы можете получить ошибку, проверив new.target следующим образом:

function add(x, y) {
    if (new.target) {
        throw 'The add function cannot be called as a constructor';
    }
    return x + y;
}
let obj = new add(10, 20);
console.log(obj);

Методы функции: apply, call и bind

Объект функции имеет три важных метода: apply(), call() и bind().

Методы apply() и call()

Методы apply() и call() вызывают функцию с заданным значением this и аргументами.

Разница между apply() и call() заключается в том, что вам нужно передать аргументы методу apply() в виде объекта, подобного массиву, тогда как вы передаете аргументы функции call() по отдельности. Например:

let cat = {
    type: 'Cat',
    sound: 'Meow'
};
let dog = {
    type: 'Dog',
    sound: 'Woof'
};
const say = function(message) {
    console.log(message);
    console.log(this.type + ' says ' + this.sound);
};
say.apply(cat, ['What does a cat say?']);
say.apply(dog, ['What does a dog say?']);

Выход:

What does a cat sound? 
Cat says Meow 
What does a dog sound? 
Dog says Woof

В этом примере:

  • Во-первых, объявите два объекта cat и dog с двумя свойствами:
let cat = { type: 'Cat', sound: 'Meow' }; 
let dog = { type: 'Dog', sound: 'Woof' };
  • Во-вторых, определите функцию say(), которая принимает один аргумент:
const say = function(message) {
    console.log(message);
    console.log(this.type + ' says ' + this.sound);
};
  • В-третьих, вызовите функцию say() с помощью метода apply() :
say.apply(cat, ['What does a cat say?']);

В этом примере первым аргументом метода apply() является объект cat. Следовательно, объект this в функции say() ссылается на объект cat.

  • В-четвертых, вызовите функцию say() и передайте объект dog :
say.apply(dog, ['What does a dog say?']);

В этом примере this в функции say() ссылается на объект dog.

Метод call() аналогичен методу apply(), за исключением способа передачи аргументов функции:

say.call(cat, 'What does a cat say?'); 
say.call(dog, 'What does a dog say?');

Метод bind()

Метод bind() создает новый экземпляр функции, чье значение this привязано к предоставленному вами объекту. Например:

Сначала определите объект с именем car :

let car = {
    speed: 5,
    start: function() {
        console.log('Start with ' + this.speed + ' km/h');
    }
};

Затем определите другой объект с именем aircraft :

let aircraft = {
    speed: 10,
    fly: function() {
        console.log('Flying');
    }
};

aircraftне имеет метода start(). Чтобы запустить aircraft, вы можете использовать метод bind() метода start() объекта car :

let taxiing = car.start.bind(aircraft);

В этом операторе мы меняем значение this внутри метода start() объекта car на объект aircraft. Метод bind() возвращает новую функцию, назначенную переменной taxiing.

Теперь вы можете вызвать метод start() через переменную taxiing :

taxiing();

Он покажет следующее сообщение:

Start with 10 km/h

Далее используется метод call() для вызова метода start() объекта aircraft :

car.start.call(aircraft);

Как видите, метод bind() создает новую функцию, которую вы можете выполнить позже, в то время как метод call() выполняет функцию немедленно. В этом основное различие между методами bind() и call().

Технически объект aircraft заимствует метод start() объекта car через методы bind(), call() или apply().

По этой причине методы bind(), call() и apply() также известны как функции заимствования.

Заключение

  • Все функции являются экземплярами типа Function, то есть объектами со свойствами и методами.
  • У функции есть два важных свойства: name и prototype.
  • У функции также есть три важных метода: call(), apply() и bind().
Рейтинг
( Пока оценок нет )
Александр Русаков / автор статьи
Программист, разработчик, 12 лет опыта работы в крупных компаниях. Быстро освоил typescript, делюсь своими знаниями на страницах этого сайта.
Загрузка ...
JavaScript и TypeScript