В JavaScript вы можете заимствовать методы из других объектов для создания некоторой функциональности, не наследуя все их свойства и методы.
JavaScript предоставляет два метода для всех объектов функций, call()
и apply()
, которые позволяют вызывать функцию, как если бы это был метод другого объекта. Вот пример:
var objA = {
name: "object A",
say: function(greet) {
alert(greet + ", " + this.name);
}
}
objA.say("Hi"); // Displays: Hi, object A
var objB = {
name: "object B"
}
/* У objA нет метода say(), но он может позаимствовать его у objA */
objA.say.call(objB, "Hello"); // Выводит: Hello, object B
Какая разница между методами call() и apply()
Синтаксис метода apply()
практически идентичен call()
, единственное отличие состоит в том, что метод call()
принимает список аргументов, таких как call(thisObj, arg1, arg2, ...)
, тогда как apply()
принимает массив аргументов, например apply(thisObj, [argsArray])
.
Обратите внимание на квадратные скобки ([]
), которые обозначают массив, в последней строке следующего примера:
var objA = {
name: "object A",
say: function(greet) {
alert(greet + ", " + this.name);
}
}
objA.say("Hi"); // Displays: Hi, object A
var objB = {
name: "object B"
}
/* У objA нет метода say(), но он может позаимствовать его у objA */
objA.say.apply(objB, ["Hello"]); // Выводит: Hello, object B
Использование метода apply()
Метод apply()
также позволяет вам использовать встроенные методы для быстрого и простого выполнения некоторых задач. Одним из таких примеров является использование Math.max()
/Math.min()
для определения максимального или минимального значения в массиве, в противном случае эта задача потребовала бы зацикливания значений массива.
Как вы уже знаете из предыдущих глав, у массивов JavaScript нет метода max()
, но у Math есть, поэтому мы можем применить метод Math.max()
, например:
var numbers = [2, 5, 6, 4, 3, 7];
// Используем Math.max
var max = Math.max.apply(null, numbers);
alert(max); // Выводит: 7
Первым аргументом для call()
и apply()
является объект, для которого должна быть вызвана функция. Использование null
в качестве первого аргумента похоже на вызов функции без предоставления какого-либо объекта для указателя this
внутри функции.
Новый оператор распространения ES6 обеспечивает более короткий способ получения максимального или минимального значения из массива без использования метода apply()
. Вот пример:
var numbers = [2, 5, 6, 4, 3, 7];
// Использование оператора spread
var max = Math.max(...numbers);
alert(max); // Выводит: 7
Тем не менее, как spread (…)
, так и apply()
либо потерпят неудачу, либо вернут неверный результат, если в массиве слишком много элементов (например, десятки тысяч). В этом случае вы можете использовать Array.reduce()
, чтобы найти максимальное или минимальное значение в числовом массиве, сравнивая каждое значение следующим образом:
var numbers = [2, 5, 6, 4, 3, 7];
// Использование оператора reduce
var max = numbers.reduce(function(a, b) {
return Math.max(a, b);
});
alert(max); // Выводит: 7