Rhino не перечисляет «аргументы» функции

Я пытаюсь использовать переменную «аргументы», доступную для функции, чтобы перечислить аргументы, переданные функции, в Javascript, используя:

for (var i in arguments){
   ...
}

Кажется, это работает для меня в консолях chrome и firebug, но не работает с Rhino. С первыми двумя я могу успешно войти в цикл for и увидеть аргументы, в то время как с последним, похоже, что цикл for даже не вводится.

Почему это происходит и как я могу предотвратить это?


person Anonymous    schedule 10.08.2011    source источник
comment
можете ли вы подтвердить, что arguments содержит значения, которые, по вашему мнению, есть?   -  person Thilo    schedule 10.08.2011
comment
Я бы ожидал, что объект, оцененный из 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.2011
comment
Привет, Тило, да, вот фрагмент моего терминала: abhinav@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.2011
comment
Однако (для плакатов) function 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.2011
comment
привет pst - другая форма for, с arguments.length, работает. Я получаю строки javascript, скалы. Почему бывшая форма не для работы? это, как вы говорите, - неправильный код - (также что вы подразумеваете под неправильным? в соответствии со спецификациями сценария ecma?)   -  person Anonymous    schedule 10.08.2011
comment
@user57257 См.: Итерация массива JavaScript, возвращающая больше значений; for(.. in ..) перечисляет (неисключенные) свойства. Это только побочный эффект реализации массива JS, который работает (иногда) для объектов массива.   -  person    schedule 10.08.2011
comment
спасибо, просто несоответствие между консолью хрома и носорога меня смутило..   -  person Anonymous    schedule 10.08.2011
comment
Для тех, кто заинтересован в ответе, stackoverflow.com/questions/4824207/ Это отвечает на этот вопрос.   -  person Anonymous    schedule 10.08.2011
comment
Это может быть одной из причин, по которой CoffeeScript копирует для вас массив аргументов в реальный массив.   -  person Thilo    schedule 10.08.2011
comment
Опубликуйте ответ (резюме заключения и ссылку) и примите его сами :)   -  person    schedule 10.08.2011


Ответы (1)


Из Javascript for..in, перебирающий аргументы, т.е. for(arg in arguments) не работает в IE8, но работает в Chrome 8:

Прежде всего, хотя объект аргументов, доступный внутри функции, не является массивом, он достаточно похож на массив, так что инкрементный цикл 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 не поддаются перечислению (как и его длина), именно поэтому вы ничего не перебираете!

person Anonymous    schedule 11.08.2011