Почему следует использовать «применить»? - PullRequest
28 голосов
/ 14 февраля 2011

Этот фрагмент вырезан из Тайны JavaScript ниндзя.

function log() {
    try {
        console.log.apply( console, arguments );
    } catch(e) {
        try {
            opera.postError.apply( opera, arguments );
        } catch(e){
            alert( Array.prototype.join.call( arguments, " " ) );
        }
    }
}

Почему я должен использовать apply и в чем разница между console.log.apply(console, arguments) и console.log(arguments)?

Ответы [ 5 ]

36 голосов
/ 14 февраля 2011

В этом случае функция журнала может принимать любое количество аргументов.

Используя .apply(), не имеет значения, сколько аргументов передано.Вы можете задать для набора console.log(), и они будут получены в качестве отдельных аргументов.

Так что если вы сделаете:

console.log(arguments)

... вы на самом деле даете console.log aодин Arguments объект.

Но когда вы делаете:

console.log.apply( console, arguments );

... это как если бы вы передали их отдельно.

Другие полезные примеры использования .apply() как это может быть продемонстрировано в других методах, которые могут принимать переменное число аргументов.Одним из таких примеров является Math.max().

Типичный вызов выглядит следующим образом:

var max = Math.max( 12,45,78 );  // returns 78

... где возвращается наибольшее число.

Что если вы на самом делеесть массив значений, из которых вам нужно наибольшее?Вы можете использовать .apply() для передачи коллекции.Math.max будет думать, что они были отправлены как отдельные аргументы вместо массива.

var max = Math.max.apply( null, [12,45,92,78,4] );  // returns 92

Как вы можете видеть, нам не нужно заранее знать, сколько аргументов будет передано.Массив может иметь 5 или 50 предметов.Это будет работать в любом случае.

13 голосов
/ 14 февраля 2011

Если у вас есть

function log() {
    console.log.apply(console, arguments);
}

и вы называете его как log('foo');, то это означает console.log.apply(console, ['foo']);, что эквивалентно console.log('foo');, что вы и хотите.

Если выопределил его как

function log() {
    console.log(arguments);
}

, тогда log('foo'); будет эквивалентно log(['foo']);, что не то, что вы хотите.

6 голосов
/ 30 сентября 2015

Давайте обсудим некоторые предпосылки, почему apply существуют специально, когда у нас есть метод call с похожим синтаксисом.

Сначала нам нужно разобраться в некоторых темах:

Функция Variadic:

В компьютерном программировании это функция, которая может принимать любое количество аргументов.

Структура данных JavaScript:

В javascript, если мы имеем дело с данными, чем чаще всего используются структуры данных, это массив, и в большинстве случаев мы получаем данные в виде массива.

Теперь, если мы выполняем какую-либо переменную функцию в javascriptчем наш вызов будет выглядеть следующим образом -

average - это функция с переменным числом аргументов, и ее вызов будет выглядеть следующим образом:

average(1,2,3);
average(1);
average(3,5,6,7,8);

и, если получаются данные в формате массива (в большинстве случаевВ тех случаях, когда мы получим данные в формате массива для функций Variadic), мы должны вызывать нашу функцию как -

average(array[0],array[1],array[2],array[3],.... and so on)

Что, если мы получили массив длиной 100 элементов, мы напишем его так?

Нет, мы хаve apply метод, который был разработан именно для этой цели.

average.apply(null,array);
6 голосов
/ 14 февраля 2011

Функция apply изменяет значение this в вызываемом объекте, а также позволяет передавать массив для аргументов.

Например, если вы хотите передать массив в качестве аргументов функции:

function foo(value1, value2, value3) {
    alert("Value 1 is "+value1+".");
    alert("Value 2 is "+value2+".");
    alert("Value 3 is "+value3+".");
}
var anArray=[1, 2, 3];
foo(anArray); // This will not work. value1 will be anArray, and value 2 and 3 will be undefined.
foo.apply(this, anArray); // This works, as anArray will be the arguments to foo.

Или другое использование: изменение this:

function Foo() {
    this.name="world";
    this.sayHello=function() {
        alert("Hello, "+this.name);
    };
}
var foo=new Foo();
foo.sayHello(); // This works, as this will be foo in foo's sayHello.
var sayHello=foo.sayHello;
sayHello(); // This does not work, as this will not be foo.
sayHello.apply(foo, []); // This will work, as this will be foo.
0 голосов
/ 14 февраля 2011

console.log(arguments) будет отправлять один аргумент в console.log, массив аргументов, передаваемых вашему методу журнала.console.log.apply(console, arguments) отправляет возможно несколько аргументов как несколько аргументов вместо одного массива.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...