Контекст функции — это объект, относительно которого совершается вызов.
Контекст доступен внутри функции с помощью ключевого слова this
.
Контекст активно используется при написании методов.
var cat = {
name: 'Tom',
say: function() {
console.log('%s says Meowww!', this.name);
}
}
cat.say(); // Tom says Meowww!
Другими словами, при вызове функции с помощью точки (как в cat.say()
) контекстом становится объект, который находится слева от точки.
Функцию можно вызвать с другим контекстом с помощью метода call
.
var tom = {
name: 'Tom',
say: function() {
console.log('%s says Meowww!', this.name);
}
};
var barsick = {
name: 'Barsick'
}
tom.say.call(barsick); // Barsick says Meowww!
В этом примере мы вызвали метод say
из объекта tom
, но сделали это действие относительно объекта barsick
.
Внутри функции доступен объект arguments
, который содержит список всех аргументов, с которыми вызвана функция.
function varargs() {
console.log(arguments);
}
varargs(1,2,3,'Hi!');
// [1, 2, 3, 'Hi!']
Осторожно! Объект arguments
не является массивом.
Вы не можете использовать привычные методы push
, pop
, map
, filter
и так далее.
Вам доступно только свойство length
— количество аргументов, а также доступ по индексам.
Объект arguments
можно легко преобразовать в массив с помощью метода slice
:
var args = [].slice.call(arguments);
args.push('Hello'); // Теперь это работает!
Метод slice
, вызванный без аргументов, возвращает копию исходного массива. Трюк состоит в изменении контекста: мы вызываем метод массива относительно объекта arguments
.
Используя arguments
, Вы можете написать функцию, которая принимает произвольное количество аргументов.
Пример такой функции — console.log
:
console.log('Simple message');
console.log('Message with %s', 'parameter');
console.log('Message and %s %s', 'two', 'parameters');
Динамический вызов используется, когда набор аргументов для вызова функции является вычисляемой величиной.
Динамический вызов осуществляется с помощью метода apply
.
var messages = [
['Bob ate %s and %s', 'carrot', 'cucumber'],
['Alice ate %s', 'banana'],
['Tom didn\'t eat anything']
];
messages.forEach(function(msgArr) {
console.log.apply(console, msgArr);
});
// Bob are carrot and cucumber
// Alice ate banana
// Tom didn't eat anything
Методы call
и apply
схожи:
метод call
принимает следующие аргументы по одному (т.е. также, как в исходной функции);
.call(<thisArg>[, param1][, param2...])
метод apply
принимает массив аргументов:
.apply(<thisArg>[, argsArray])
Запомнить легко по букве a: apply
начинается на a, также как и array
.
arguments
в массив.
call
и apply
.