Итак, у меня есть 3 функции:
function a() {
arguments[0]();
}
function b(fn) {
fn();
}
function c() {
console.info(this);
}
Теперь рассмотрим выходы:
a(c) // Arguments
b(c) // Window
a(() => {console.info(this}) // Window
b(() => {console.info(this)}) // Window
Почему a(c) выводит аргументы, пока он является оконным (с учетом нестрогих) во всех остальных случаях?
Потому что arguments[0](); - это вызов метода.
Спасибо @Bergi. Мне потребовалось время, чтобы осмыслить это



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


В JavaScript this обычно относится к объекту, из которого была вызвана функция (если это не стрелочная функция). Так, например, если мы сделаем что-то вроде этого:
var obj = { fun: function() { console.info(this); } }
var obj1 = { fun: obj.fun, otherProperty: 123 }
obj.fun(); // equivalent to obj["fun"]()
obj1.fun(); // equivalent to obj1["fun"]()Мы обнаружим, что в первом вызове this ссылается на obj, а во втором - на obj1, хотя это та же функция.
Теперь переменная arguments - это объект, в котором хранятся все аргументы, переданные функции. Если аргумент был функцией и вы обращаетесь к нему через объект arguments, он становится «родительским» объектом, из которого была вызвана функция, и становится новым this в контексте выполнения функции. Вы можете считать свой случай примерно таким:
function c() {
console.info(this);
}
var arguments = { "0" : c }
arguments["0"]() // will log the arguments objectВо втором вызове (b(c)) функция, переданная в качестве аргумента, вызывается непосредственно внутри родительской функции, без доступа к ней через прокси-объект - в этом случае this будет скопирован из родительской области выполнения, которой является window.
В третьем и четвертом примере обе функции определены с помощью функции стрелки, которая сохраняет значение this из контекста, в котором они были созданы, и предотвращает изменение этого значения.
Подробнее о стрелочных функциях: Стрелочные функции
Единственный, казалось бы, странный случай здесь - это первый. С
foo.bar(),fooбудет таким. Это эквивалентfoo["bar"](), следовательно, он также эквивалентенarguments[0]().