Метод call() в JavaScript с примерами

В этом руководстве вы узнаете о методе JavaScript call() и о том, как использовать его более эффективно на примерах.

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

Пример:

function add(x, y) {
    return x + y;
}
console.log(add instanceof Function); // true

Тип Function.prototype имеет метод call() со следующим синтаксисом:

functionName.call(thisArg, arg1, arg2, ...);

В этом синтаксисе метод call() вызывает функцию functionName с аргументами( arg1, arg2, …) и this устанавливает объект thisArg внутри функции.

  • thisArg — это объект, на который ссылается this объект внутри функции functionName.
  • arg1, arg2, .. — это аргументы функции, переданные в functionName.

Метод call() возвращает результат вызова functionName().

В следующем примере функция add() определяется и вызывается как обычно:

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

Следующий код вызывает функцию add(), но вместо этого использует метод call() :

function add(x, y) {
    return x + y;
}
let result = add.call(this, 10, 20);
console.log(result); // 30

По умолчанию this внутри функции устанавливается на глобальный объект, т. е. window в веб-браузерах и global в Node.js.

Обратите внимание, что в строгом режиме this внутри функции имеет значение undefined вместо глобального объекта.

Рассмотрим следующий пример:

var greeting = 'Hi';
var messenger = {
    greeting: 'Hello'
}
function say(name) {
    console.log(this.greeting + ' ' + name);
}

Внутри функции say() мы ссылаемся на greeting через значение this. Если вы просто вызовете функцию say() с помощью метода call():

say.call(this,'John');

Он покажет следующий вывод на консоль:

"Hi John"

Однако, когда вы вызываете метод call() объекта функции say и передаете объект messenger в качестве значения this :

say.call(messenger,'John');

Вывод будет:

"Hello John"

В этом случае значение this внутри функции say() ссылается на объект messenger, а не на глобальный объект.

Использование для цепочки конструкторов объекта

Вы можете использовать метод call() для объединения конструкторов объекта. Рассмотрим следующий пример:

function Box(height, width) {
    this.height = height;
    this.width = width;
}
function Widget(height, width, color) {
    Box.call(this, height, width);
    this.color = color;
}
let widget = new Widget('red', 100, 200);
console.log(widget);

Выход:

Widget { height: 'red', width: 100, color: 200 }

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

  • Во-первых, инициализируйте объект Box с двумя свойствами: height и width.
  • Во-вторых, вызовите метод call() объекта Box внутри объекта Widget, задайте значение this для объекта Widget.

Заимствование функций

В следующем примере показано, как использовать метод call() для заимствования функций:

const car = {
    name: 'car',
    start() {
        console.log('Start the ' + this.name);
    },
    speedUp() {
        console.log('Speed up the ' + this.name);
    },
    stop() {
        console.log('Stop the ' + this.name);
    },
};
const aircraft = {
    name: 'aircraft',
    fly() {
        console.log('Fly');
    },
};
car.start.call(aircraft);
car.speedUp.call(aircraft);
aircraft.fly();

Выход:

Start the aircraft Speed up the aircraft Fly

Как это работает:

  • Во-первых, определите объект car с одним именем свойства и тремя методами start, speedUp и stop:
const car = {
    name: 'car',
    start() {
        console.log('Start the ' + this.name);
    },
    speedUp() {
        console.log('Speed up the ' + this.name);
    },
    stop() {
        console.log('Stop the ' + this.name);
    },
};
  • Во-вторых, определите объектaircraft с одним именем свойства и методом:
const aircraft = {
    name: 'aircraft',
    fly() {
        console.log('Fly');
    },
};
  • В-третьих, вызовите методы start() и speedUp() объекта car и метод fly() объекта aircraft. Однако передайте aircraft в качестве первого аргумента в методы start() и speedUp() :
car.start.call(aircraft); 
car.speedUp.call(aircraft); 
aircraft.fly();

Внутри методов start() и speedUp() this ссылается на объект aircraft, а не на объект car. Таким образом, this.name возвращает 'aircraf'. Следовательно, методы выводят следующее сообщение:

Start the aircraft 
Speed up the aircraft

Технически объект aircraft заимствует методы start() и speedUp() объекта car. А заимствование функций относится к объекту, который использует метод другого объекта.

В следующем примере показано, как объект arguments заимствует метод filter() из Array.prototype через функцию call() :

function isOdd(number) {
    return number % 2;
}
function getOddNumbers() {
    return Array.prototype.filter.call(arguments, isOdd);
}
let results = getOddNumbers(10, 1, 3, 4, 8, 9);
console.log(results);

Выход:

[ 1, 3, 9 ]

Как это работает:

  • Во-первых, определите isOdd(), которая возвращает true, если число является нечетным:
function isOdd(number) { 
    return number % 2; 
}
  • Во-вторых, определите getOddNumbers(), которая принимает любое количество аргументов и возвращает массив, содержащий только нечетные числа:
function getOddNumbers() { 
    return Array.prototype.filter.call(arguments, isOdd); 
}

В этом примере объект arguments заимствует метод filter() объекта Array.prototype.

  • В-третьих, вызовите getOddNumbers() :
let results = getOddNumbers(10, 1, 3, 4, 8, 9); 
console.log(results);
Рейтинг
( Пока оценок нет )
Александр Русаков / автор статьи
Программист, разработчик, 12 лет опыта работы в крупных компаниях. Быстро освоил typescript, делюсь своими знаниями на страницах этого сайта.
Загрузка ...
JavaScript и TypeScript