Чем заменить continue
Подскажите пожалуйста, чем заменить continue для такого кода:
continue - естественно так не работает. Есть ли в JS - аналог оператора goto, который бы так сработал ? function my_func(numm) { if(numm == 1) { continue jump; } console.log("check_1"); if(numm == 2) { continue jump; } console.log("check_2"); if(numm == 3) { continue jump; } console.log("check_3"); jump: console.log("jump"); } my_func(2); |
|
function my_func(numm){ jump: { if(numm == 1) break jump; console.log("check_1"); if(numm == 2) break jump; console.log("check_2"); if(numm == 3) break jump; console.log("check_3"); } console.log("jump"); } my_func(2); |
Спасибо!
|
Тока за такое руки отрывают и в любых нормальных конфигах оно запрещено.
|
Цитата:
|
Цитата:
А людям свойственно ошибаться. Или выдавать свое частное мнение за Истину. |
Это запрещено по той же причине что и goto - мозголомное запутывание кода. Очень мало людей назовут это ошибкой.
|
Много, чего можно назвать запутыванием кода.
Тот же break в цикле, разве не подобен goto? Тот же break в swinch - case разве не служит той же цели - пропустить что то и выйти из блока. От goto break отличается тем, что передает управление не куда угодно, а просто завершает выполнение блока, подобно, как if () return; завершает функцию. if () return не запрещен? А то ведь это тоже нарушает парадигму структурного программирования, согласно которой у функции (подпрограммы) должен быть один вход и один выход. |
Присoeдинюсь к дискуссии.
Лично меня тоже напрягает ограниченность break/continue. Почему нельзя указать число с указанием уровня вложенности для их действия? Примерно вот так: for(i = 0; i < x; ++ i) { for(j = 0; j < y; ++ j) { for(k = 0; k < z; ++ k) { if(k == i) continue 1; // continue 0 / continue - продолжение текущего блока (for k) // continue 1 - продолжение блока на 1 уровень выше (for j) // continue 2 - продолжение блока на 2 уровня выше (for i) switch(m[k]) { case false: break 2; // break - выйти из switch // break 0 - выйти из текущего цикла (for k) // break 1 - выйти из цикла на 1 уровень выше (for j) // break 2 - выйти из цикла на 2 уровня выше (for i) } } console.log("Покинули цикл for k"); if(i == j) break 2; // выходим из цикла двумя уровнями выше (for i) switch(m[j]) { case true: continue 1; // продолжение блока на 1 уровень выше (for i) } } console.log("Покинули цикл for j"); } |
Alikberov, лол, потому что это запутает код ещё больше. С метками то уже ад, с цифрами - вообще полное безумие.
Попади я на такой код, я бы реально задумался о рукоприкладстве вживую, а не через монитор.) Это тут у тебя три цикла сразу подряд и выполняют полтора действия(и то с полпинка не рабирёшься), а попробуй представить себе реальный цикл с этим дерьмом. |
Цитата:
Но, на крайний случай такие механизмы не помешали бы, однако, с примечанием, что не рекомендуется к обильному использованию и валидаторы не пропустят, если на весь код приходится больше процента. Но, правда: Иногда, в очень узких местах, указание уровня действия не помешало бы, чем вкладывать в цикл функцию с циклом и прерываться по return true/false, типа: for(i = 0; i < x; ++ i) { if(function() { for(j = 0; j < y; ++ j) { if(i == j) return false; } }) continue; }Что ещё хуже. |
Alikberov, по-хорошему - разбить всё на отдельные функции с говорящими именами и вызывать одну из другой.
Максимум для цикла двойная вложенность и то только в простых случаях. |
Цитата:
|
Вообще в программировании существуют много спорных ситуаций, про которые есть прямо противоположные мнения. Стоит так делать или нет. С одной стороны "удобочитаемость", с другой стороны эффективность.
Это и break, и вложенные тетрарные операции, и использование блоков для инкапсуляции переменных, и обязательное закрытие тегов в html.... Удобочитаемость, как мне кажется - дело привычки и понимания кода. Доходит до того, что ругань идет по поводу x | 0 для взятия целой части. Мол это не понятно, и всегда надо Math.floor. А вдруг, кому то не понятно x++? Тогда надо всегда х += 1; использовать? Хотя кому то и это может быть не понятно. Тогда уж x = x+ 1; И только так. |
Цитата:
|
Цитата:
Тем более, когда тело функции синтезируется по шаблону при запуске скрипта. Цитата:
А «x | 0» выглядит не так интуитивно, как «x.0»…:yes: Тем более, в условиях форума «Math.floor(x)» - слишком громоздкая запись… |
voraa,
x | 0 - неудачный пример для js Math.floor - работает быстрее и с большими числами const a = Math.pow(2, 52) / 3; console.log(a, a|0, Math.floor(a)); alert((a|0) === Math.floor(a)) |
Цитата:
Для меня большие целые числа - экзотика. Цитата:
|
Цитата:
И приобрёл множество Думаю, не было бы большой проблемой добавить подобную фишку округления до указанного порядка: console.log(Math.PI.0); // 3 console.log(Math.PI.1); // 3.1 console.log(Math.PI.2); // 3.14 console.log(Math.PI.3); // 3.141 console.log(Math.PI.4); // 3.1415 console.log(Math.PI.5); // 3.14159Чем выражение «Math.floor(x * 10 ** n) / 10 ** n» (иногда это требуется)… (Хотя Фортрановский ** ввели совсем недавно тоже.) |
Это всё херня, я вот жду когда рефы введут.
Что-то типа: let foo = 1; function set2(bar*) { bar = 2; } set2(foo); console.log(foo) // 2 Вот тогда то всё и сломают полностью.) |
Цитата:
Хотя, да. Иногда (лично мне) приходилось буквально на ощупь несколько раз переписывать выражение, чтобы всё заработало как надо.:lol: А «x.0 … x.25» - нигде не встречается и её можно безопасно вводить в спецификацию… |
Цитата:
Свойство после "." должно быть задано идентификатором, а не числом или еще чем либо. Если в x.0 "0" это свойство, то такими же свойcтвами должны быть и любые другие числа (x.1, x.42 .... ) А как на счет x.3.14159? |
Цитата:
Я вот только слышал про неизменяемые массивы (кртеж, tuple) и неизменяемы простые объекты (record) Цитата:
А в js рефы и так есть let x = {a: 0, b: 1} В х содержится не объект, а ссылка на объект. |
Цитата:
|
Это не поломало существующий синтаксис и не привело к синтаксическим неоднозначностям. Просто введены новые операции, задаваемы новыми синтаксическими конструкциями ("??", "?."). Никакие старые синтаксисы и правила при этом не затронуты. Это так же безболезненно, как была введена операция "**"
Никто не будет вводить новую операцию для обращения к свойству, заданному чиcлом, т.к. такая операция уже есть - x[0]. |
Цитата:
Которое больше как фонит тем что вы не разобрались в разнице , мол эзотерика. Нет эзотерики, код для шага цикла ничего не возвращает, поэтому для него нет разницы, и писать ++i несколько паливно |
Цитата:
Я бы его отнес к такому запаху кода как "obscured intent". В коде у нас побитовая операция, но производим мы не ее, а использует ее сайдэффект по отбрасыванию дробной части и знание что "или" с "нулем" ничего не изменит. Цитата:
|
Цитата:
Надо знать все особенности выполнения операции. Так же как надо знать все особенности ++x и x++ - то, что это не просто прибавление 1 к x Так же, как знать особенности выполнения операций && и || (то, что логические значения только вычисляются, но не возвращаются) Человек, читающий код должен знать это. Тогда ему будет понятно. |
Цитата:
В js почему то так вышло, что везде очень много тонкостей, пример - дока к оператору "==", которые видимо предлагается учить наизусть, когда это твой один язык в стеке, то куда не шло, а иначе ... |
Цитата:
Но когда мы пишем m = n++; мы учитываем все особенности этой операции. Что такое побитовая операция? Если просто так сказать, то можно подозревать, что мы берем битовое представление аргумента (если это вещественное число, то все его 64 разряда м мантиссой и порядком) и работаем с этими битами. Но это не так. Мы же учитываем, что оно сначала преобразуется в 32 разрядное целое. Что такое логическая операция &&? В фортране или паскале тоже есть логические операции (.AND. и and соответственно). Но если он пришел в js, то стек ни стек, а как выполняется && знать придется. Так же как придется знать, что во что прeобразуется при '10'+1 и при '01' == 1 и при x|0 |
Не сравнивайте с ++ или &&.
Побитовые операции - очень редкие на самом деле по статистике использования в web стеке, использовать их для других задач - ненужно усложнять код такими низкоуровневыми деталями. Вон в доках есть более забористые вещи - ~str.indexOf("Widget") - как аналог != -1 , из всего этого можно такую шифрограмму составить, как будто ни Роберт Мартин ни Фаулер никогда и ни для кого своих книг не писали |
Я вот люблю битовые флаги, типа:
const Action = { DEFAULT: 0b000000000, // do nothng DELETE: 0b000000001, // to trash ARCHIVE: 0b000000010, // to archive FINALIZE: 0b000000100, // remove "new" label and star ADD_LABEL: 0b000001000, // add specified label READ: 0b000010000, // mark as read } ... return Action.READ | Action.ARCHIVE | Action.FINALIZE; ... if(action & Action.ARCHIVE) { removeInboxIds.push(id); } Но сейчас такое уже считается сложна, эх... |
Используются иногда.
Например в createNodeIterator https://developer.mozilla.org/en-US/...teNodeIterator Но чаще в С |
const access = (value, action) => Boolean( value & { read: 1, create: 2, edit: 4, delete: 8, }[action] ); for (let i = 0; i < 16; i++) { let res = []; if (i & 1) res.push('read'); if (i & 2) res.push('create'); if (i & 4) res.push('edit'); if (i & 8) res.push('delete'); console.log(i, res, (i).toString(2).padStart(4, '0')); } console.log(access(3, 'edit')); console.log(access(15, 'delete')); Редко, но используем, в базах данных с типами set, enum без них никак |
Цитата:
А раз разницы нет - есть свобода для проявления индивидуально творческого стиля. Иногда вообще пишут «I+++j»…:-/ Цитата:
const C_Struct = { Field_1 :1, // 1 бит Field_2 :2, // 2 бита Field_3 :2, // 2 бита Field_4 :3 // 3 бита } var MyFields = { _struct :C_Struct, Fields :0x9D } function Read_CStruct(Struct, Field) { var i = 0; for(var id in Struct._struct) { if(id == Field) return (Struct.Fields >> i) & ~(-1 << Struct._struct[id]); i += Struct._struct[id]; } } console.log(`Field_3: ${Read_CStruct(MyFields, "Field_3")}`); |
Цитата:
|
voraa, а я бы нет.)
|
Цитата:
исходный код должен понятен большинству а там может быть сборщик, минификатор, обфускатор ... |
Цитата:
Вспоминается COBOL, где надо было писать MULTIPLY X BY Y. А что? Всем ведь понятно. X*Y не каждому дано понять. |
Часовой пояс GMT +3, время: 16:19. |