Прежде всего, хотя объект arguments, доступный внутри функции, не является массивом, он достаточно «массивоподобен», так что для него используется инкрементный цикл for (for (var i = 0, len = arguments.length; i < len; i ++) {...}) предпочтительнее - не только потому, что он работает быстрее, но и потому, что он избегает других ловушек - одна из которых - то, к чему вы попадаете.
Чтобы действительно ответить на вопрос, почему второй цикл не работает, важно понять, что делает цикл for ... in: он перебирает все перечисляемые свойства, найденные в объекте. Теперь я выделил 2 слова в этом утверждении, потому что я использовал эти два слова целенаправленно, чтобы указать на пару нюансов, которые, хотя они могут показаться тонкими, могут кардинально повлиять на поведение вашего кода, если вы не понимаете, что происходит .
Сначала давайте сосредоточимся на всем - под этим я подразумеваю не только свойства самого объекта, но также и потенциально свойства, которые указанный объект унаследовал от своего прототипа, или прототипа своего прототипа, и так далее. По этой причине очень часто рекомендуется «охранять» любой цикл for ... in, немедленно дополнительно дополнительно квалифицируя его условием if (obj.hasOwnProperty (p)) (при условии, что ваш цикл был написан для (var p in obj). )).
Но это не то, с чем вы здесь сталкиваетесь. Для этого давайте сосредоточимся на этом втором слове, перечисляемом. Все свойства объектов в JavaScript являются перечисляемыми или не перечисляемыми, что напрямую связано с тем, отображается ли свойство в цикле for ... in или нет. В браузерах, таких как Firefox и IE, оказывается, что числовые свойства объекта arguments не перечисляются (равно как и его длина), и именно поэтому вы ничего не просматриваете!