Прежде всего, хотя объект аргументов, доступный внутри функции, не является массивом, он достаточно похож на массив, так что инкрементный цикл 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 не поддаются перечислению (как и его длина), именно поэтому вы ничего не перебираете!
arguments
, по крайней мере, будет иметь свойстваlength
иcaller
иcallee
... так как они требуются согласно спецификации. Обратите внимание, что формаfor(var x in arrLikeThing)
обычно является неправильным кодом. Сравните сfor(var i = 0; i < argumets.length; i++) { var arg = arguments[i]; ... }
. - person   schedule 10.08.2011abhinav@abhinav:~/js_codes$ cat testfunc.js function main(){ for(var i in arguments) print(i); } a = main("javascript", "rocks"); abhinav@abhinav:~/js_codes$ rhino testfunc.js abhinav@abhinav:~/js_codes$
- person Anonymous   schedule 10.08.2011function x () { var i = 0; for(var x in arguments) { i++ }; return i }; alert(x(...))
в FF5 вернет 0, где ... равно `` и 1, где ... равно"hello"
и т. д. Первый комментарий вводил в заблуждение; то, что у объекта есть свойство, не означает, что свойство должно быть перечислено с помощьюfor...in
. Я не уверен, что спецификация говорит wrt.arguments
в этом. (Было бы интересно посмотреть, как приведенный выше код работает в Rhino [например, вне FF].) - person   schedule 10.08.2011for(.. in ..)
перечисляет (неисключенные) свойства. Это только побочный эффект реализации массива JS, который работает (иногда) для объектов массива. - person   schedule 10.08.2011