Зачем вызывать «применить» вместо прямого вызова функции? - PullRequest
12 голосов
/ 09 мая 2011

При просмотре исходного кода для Raphael или g.raphael или других библиотек я заметил, что разработчик делает нечто подобное:

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

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

var val = Math.max(data_array);

Спасибо.

Ответы [ 5 ]

13 голосов
/ 09 мая 2011

Math.max по умолчанию не принимает список.«apply» позволяет распаковать список с аргументами, чтобы max работал правильно.

11 голосов
/ 09 мая 2011

Я думаю, что объяснение из Mozilla Docs хорошо описывает это:

Вы можете назначить другой этот объект при вызове существующей функции. this относится к текущему объекту, вызывающему объекту.С помощью apply вы можете написать метод один раз, а затем наследовать его в другом объекте, без необходимости переписывать метод для нового объекта.

apply очень похож на call, за исключением того типа аргументов, который он поддерживает.Вы можете использовать массив аргументов вместо именованного набора параметров.С помощью apply вы можете использовать литерал массива, например fun.apply (this, [name, value]), или объект Array, например fun.apply (this, new Array (name, value)).

Что касается параметров:

thisArg Определяет значение this внутри забавы.Если thisArg равно нулю или не определено, this будет глобальным объектом.В противном случае это будет равно Object (thisArg) (который является thisArg, если thisArg уже является объектом, или String, Boolean или Number, если thisArg является примитивным значением соответствующего типа).Поэтому всегда верно, что typeof this == "object" при выполнении функции.

argsArray Массив аргументов для объекта, указывающий аргументы, с которыми следует вызывать fun, илиnull или 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 голосов
/ 13 декабря 2013

Зачем вызывать «apply» вместо прямого вызова функции? Давайте иметь фрагмент:

var obj = {a: "apply"};
func.call(obj, "parameter");
function func(para) {
    if(this.a === "apply"){
        console.log('apply'); 
     }
} 

Здесь мы можем видеть, что мы используем 'this' (контекст) внутри функции. Если мы напрямую вызываем функцию, то у нас нет контекста, тогда он принимает window контекст, что неправильно. Итак, если вы используете контекст внутри своей функции, тогда используйте метод apply.

0 голосов
/ 27 октября 2015

Обычно вы должны использовать apply() и call(), чтобы иметь возможность установить контекст или объект, к которому принадлежит вызывающая функция.Затем функция фактически становится методом этого объекта / контекста, который полезен, если вам нужно получить доступ к полям контекста.

Вот как Javascript изначально вызывает функции:

  1. Составьте список аргументов (argList) из параметров от 1 до конца
  2. Первый параметр thisValue
  3. Вызов функции с этим набором thisValue и argList в качестве списка аргументов

Ссылка: Понимание вызова функций JavaScript и "this" by Yehuda Katz

Итак, при непосредственном вызове функции вы фактически неявно передаетеконтекст по умолчанию для функции.Javascript передает 'window' или 'undefined' в качестве контекста, когда вы не указываете его, используя call() или apply()

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

0 голосов
/ 18 декабря 2014

.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
...