Зачем вызывать "применять" вместо прямого вызова функции?
Если посмотреть на исходный код для raphael или g.raphael или других библиотек, я заметил, что разработчик делает что-то вроде этого:
var val = Math.max.apply(Math, data_array);
Почему бы просто не вызвать функцию напрямую, например:
var val = Math.max(data_array);
Спасибо.
Ответы
Ответ 1
Я думаю, что объяснение из Mozilla Docs хорошо описывает:
Вы можете назначить другой объект при вызове существующей функции. это относится к текущему объекту, вызывающий объект. Применяя, вы можете написать метод один раз, а затем наследовать это в другом объекте, без переписать метод для нового объект.
применяется очень похоже на вызов, кроме для типа аргументов, который он поддерживает. Вместо этого вы можете использовать массив аргументов именованного набора параметров. С apply, вы можете использовать литерал массива, например, fun.apply(это, [имя, value]) или объект Array для Например, fun.apply(это, новый Массив (имя, значение)).
Что касается параметров:
thisArg Определяет ценность этого внутри fun. Если thisArg имеет значение null или undefined, это будет глобальный объект. В противном случае это будет равным к объекту (thisArg) (который является thisArg если thisArg уже является объектом или String, Boolean или Number, если thisArg является примитивным значением соответствующий тип). Следовательно, это всегда верно, что typeof этого == "объект", когда функция выполняет.
argsArray Аргумент аргумента для объекта, определяющий аргументы, с которыми забава должна быть вызвана или нулевая или undefined, если аргументы не должны быть предоставляемой функции.
Документы дают хороший пример использования для применения. В приведенном ниже примере apply применяется для привязки конструктора:
function product(name, value)
{
this.name = name;
if (value >= 1000)
this.value = 999;
else
this.value = value;
}
function prod_dept(name, value, dept)
{
this.dept = dept;
product.apply(this, arguments);
}
prod_dept.prototype = new product();
// since 5 is less than 1000 value is set
var cheese = new prod_dept("feta", 5, "food");
// since 5000 is above 1000, value will be 999
var car = new prod_dept("honda", 5000, "auto");
Обратите внимание, что в конструкторе prod_dept
поставляемый this
относится к объекту prod_dept
, а arguments
- массив аргументов, переданных конструктору product
.
Ответ 2
Math.max не будет принимать список по умолчанию. "apply" позволяет распаковать список на аргументы, чтобы max работал правильно.
Ответ 3
Зачем вызывать "применять" вместо прямого вызова функции? Пусть есть фрагмент:
var obj = {a: "apply"};
func.call(obj, "parameter");
function func(para) {
if(this.a === "apply"){
console.log('apply');
}
}
Здесь мы видим, что мы используем 'this'
(контекст) внутри функции. Если мы вызываем функцию func напрямую, чем у нас нет никакого контекста, мы будем использовать контекст window
, что неверно. Итак, если вы используете контекст в своей функции, чем использовать метод apply
.
Ответ 4
.apply
часто используется, когда намерение состоит в том, чтобы вызвать переменную функцию со списком значений аргументов, например.
Функция Math.max([value1[,value2, ...]])
возвращает наибольшее число из нуля или более.
Math.max(10, 20); // 20
Math.max(-10, -20); // -10
Math.max(-10, 20); // 20
Метод Math.max()
не позволяет передавать массив. Если у вас есть список значений, которые необходимо получить самому большому, вы обычно вызываете эту функцию, используя Function.prototype.apply(), например
Math.max.apply(null, [10, 20]); // 20
Math.max.apply(null, [-10, -20]); // -10
Math.max.apply(null, [-10, 20]); // 20
Однако, с ECMAScript 6 вы можете использовать оператор распространения:
Оператор спрединга позволяет расширять выражение в местах, где ожидаются множественные аргументы (для вызовов функций) или несколько элементов (для литералов массива).
Math.max(...[10, 20]); // 20
Math.max(...[-10, -20]); // -10
Math.max(...[-10, 20]); // 20
При вызове функции с использованием вариационного оператора вы можете даже добавить дополнительные значения, например.
Math.max(...[10, 20], 50); // 50
Math.max(...[-10, -20], 50); // 50
Ответ 5
Как правило, вы должны использовать apply()
и call()
, чтобы иметь возможность устанавливать контекст или объект, к которому принадлежит вызывающая функция. Функция тогда эффективно становится методом этого объекта/контекста, который полезен, если вам нужно получить доступ к полям контекста.
Вот как Javascript изначально вызывает функции:
- Сделать список аргументов (argList) вне параметров 1 до конца
- Первым параметром является thisValue
- Вызовите функцию с этим параметром thisValue и argList в качестве списка аргументов
Ссылка: Понимание вызова функции JavaScript и "this" Иегуда Кац
Таким образом, при непосредственном вызове функции вы фактически неявно передаете в контексте по умолчанию функцию. Javascript передает 'window'
или 'undefined'
в качестве контекста, когда вы не укажете его с помощью call()
или apply()
Этот ответ также дает пример, который может помочь в понимании использования