Подтвердить что ты не робот

Зачем вызывать "применять" вместо прямого вызова функции?

Если посмотреть на исходный код для raphael или g.raphael или других библиотек, я заметил, что разработчик делает что-то вроде этого:

var val = Math.max.apply(Math, data_array);

Почему бы просто не вызвать функцию напрямую, например:

var val = Math.max(data_array);

Спасибо.

4b9b3361

Ответ 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()

Этот ответ также дает пример, который может помочь в понимании использования