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