2010-04-05 2 views
74

Я переехал один год назад с классических языков OO, таких как Java на JavaScript. Следующий код, безусловно, не рекомендуется (или даже не исправить) в Java:Назначить переменную в условии, если условие, хорошая практика или нет?

if(dayNumber = getClickedDayNumber(dayInfo)) 
{ 
    alert("day number found : " + dayNumber); 
} 
function getClickedDayNumber(dayInfo) 
{ 
    dayNumber = dayInfo.indexOf("fc-day"); 
    if(dayNumber != -1) //substring found 
    { 
     //normally any calendar month consists of "40" days, so this will definitely pick up its day number. 
     return parseInt(dayInfo.substring(dayNumber+6, dayNumber+8)); 
    } 
    else return false; 
} 

В основном я только что узнал, что я могу присвоить переменную значение в, если условие заявления, и немедленно проверить присвоенное значение как если он булев.

Для более безопасной ставки я обычно разделяю это на две строки кода, назначая сначала, а затем проверяя переменную, но теперь, когда я нашел это, мне просто интересно, хороша ли это практика или нет в глазах опытного JavaScript Разработчики?

+0

'«Следующий код, безусловно, не рекомендуется (или событие не правильно) в Java ...»' Это даже правильно в JavaScript? Поскольку, насколько я вижу, вы возвращаете целое число ('return parseInt (...)'), если 'dayNumber! = -1' истинно, но логическое, если оно ложно. –

ответ

81

Я бы не рекомендовал его. Проблема в том, что это выглядит как общая ошибка, когда вы пытаетесь сравнить значения, но используйте один = вместо == или ===. Например, когда вы видите это:

if (value = someFunction()) { 
    ... 
} 

вы не знаете, если это то, что они имели в виду, чтобы сделать, или если они предназначены, чтобы написать это:

if (value == someFunction()) { 
    ... 
} 

Если вы действительно хотите сделать я бы рекомендовал провести явное сравнение:

if ((value = someFunction()) === <whatever truthy value you are expecting>) { 
    ... 
} 
+0

@Matthew Crumley: это отвечает на мой вопрос в ясной форме. Я не проверяю, назначая, но проверяя, какое значение оценивается после назначения. Правильно ли это понимание? –

+1

@ Майкл: Да, это правильно. Добавление сравнения в основном просто делает ваши намерения более ясными. –

+4

Последний пример не работает, однако, если вы проверяете на неудачу/успех функции, которая возвращает логическое значение. Другими словами, в то время как 'if (resultArr = myNeedle.exec (myHaystack)) {...}' работает, 'if ((resultArr = myNeedle.exec (myHaystack)) === true) {...}' не потому, что назначение resultArr всегда правдиво, даже если результат функции не является. Если кто-либо использует эту конструкцию, не забудьте сначала объявить переменную результата; «var» не является законным в условии условия if. – Ville

5

Вы также можете сделать это на Java. И нет, это не очень хорошая практика. :)

(и использовать === в Javascript для типизированного равенства Читать Крокфорд в Книге Good Parts на JS.).

+0

@quixoto: Могу ли я сделать этот трюк в Java? Интересно ... У меня нет jdk от руки atm, поэтому я не могу получить пример кода на Java. Из моей плохой памяти Java просто получит вам ошибку Runtime, если возвращаемое значение оценит что-то не логическое, как в условном выражении, правильно? –

+1

Ах, да, в Java это тип проверяется как булевский тип. Но вы * можете * делать 'if (foo = getSomeBoolValue()) {}' –

+0

Да, это так. логическую переменную, чтобы проверить, удалось ли что-то преуспеть, и другую переменную для сохранения возвращаемого значения. Вот как работает Java, я слишком хорошо знаком с этим, поэтому мне кажется странным видеть, что Javascript может делать две вещи в одной строке :) –

0

Я считаю, что это скорее стиль старой школы C; это не очень хорошая практика в JavaScript, поэтому вам следует избегать этого.

+7

Я тоже не считаю это хорошей практикой в ​​C. –

+0

Я считаю это хорошей практикой на многих языках. – JDrake

11

Я делал это много раз. Чтобы обойти предупреждение JavaScript, добавить две скобки:

if ((result = get_something())) { } 

Вы должны избегать его, если вы действительно хотите использовать его, напишите комментарий над ней говорят, что вы делаете.

+0

@SHiNKiROU: как я могу видеть предупреждения javascript? Есть ли компилятор Javascript? или интерпретатор будет генерировать какое-то предупреждение? Я использую консоль Firefox, как и отладку javascript, но никогда не вижу подобных выходов. Извините за мой ограниченный опыт. –

+4

@Michael: JSLint (http://www.jslint.com/) - популярная программа/библиотека, которая проверяет программы JavaScript на возможные ошибки или плохой код. –

+0

Используйте Mozilla Firefox с расширением Firebug и/или веб-разработчика для проверки предупреждений. –

1

Это не очень хорошая практика. Вы скоро смутитесь. Он похож на общую ошибку: неправильное использование операторов «=» и «==».

Вы должны разбить его на 2 строки кодов. Это не только помогает сделать код более четким, но и легким для рефакторинга в будущем. Представьте, что вы меняете условие IF? Вы можете случайно удалить строку, и ваша переменная больше не получает назначенное ей значение.

+0

@thethanghn: это именно то, чего я боюсь. Когда я становлюсь старше и ленив, я просто не хочу вводить код в код, если будет достаточно всего нажатия клавиш :) –

+0

Нет, я не смущаюсь, и я это делаю это все время. Для этого есть преимущества. – JDrake

3

Вы можете выполнять задания в операторах if в Java. Хорошим примером будет читать что-то и писать его:

http://www.exampledepot.com/egs/java.io/CopyFile.html?l=new

Код:

// Copies src file to dst file. 
// If the dst file does not exist, it is created 
void copy(File src, File dst) throws IOException 
{ 
    InputStream in = new FileInputStream(src); 
    OutputStream out = new FileOutputStream(dst); 

    // Transfer bytes from in to out 
    byte[] buf = new byte[1024]; 
    int len; 
    while ((len = in.read(buf)) > 0) { 
     out.write(buf, 0, len); 
    } 
    in.close(); 
    out.close(); 
} 
+0

@ Нитродист: спасибо за этот пример. Я действительно не профессионал в Java или javascript ... Хорошо знать, что этот подход также возможен в Java :) –

+0

Я не вижу смысла в этом. Вы можете сделать это на Java, PHP и многих других языках. Вопрос был в Javascript. – pmrotule

+0

Нет, это не обязательно, вам нужно внимательно перечитать вопрос. – Nitrodist

9

Я не вижу никаких доказательств того, что это не является хорошей практикой. Да, это может показаться ошибкой, но это легко исправить разумным комментарием.Возьмем, к примеру:

if (x = processorIntensiveFunction()) { // declaration inside if intended 
    alert(x); 
} 

Почему эта функция будет разрешено работать 2-й раз с:

alert(processorIntensiveFunction()); 

Поскольку первая версия выглядит плохо? Я не могу согласиться с этой логикой.

+14

Не выкопать старый комментарий, но я не согласен с вашими аргументами. Читаемый код должен объясняться без необходимости комментария - добавление комментария к запутанному коду не является средством защиты. Что касается второй части, в которой говорится, что альтернативой является вызов функции снова, я не думаю, что кто-то намеревается это сделать.Вместо этого вы будете делать 'x = processorItensiveFunction(); if (x) {alert (x); } ' – maksim

+3

@maksim: Мне нравится читаемый код, но это не обязательно означает, что код должен быть заглушен или слишком подробным. Распространение вещей по нескольким линиям и жонглирование значениями между переменными могут фактически привести к худшему коду. Вложенный код может иметь непредвиденные побочные эффекты на слабо типизированном/гибком языке, таком как JS. Назначение в условном выражении действительное в javascript, потому что ваш запрос «если назначение действительно, сделайте что-то, что может включать в себя результат назначения». Но действительно, присвоение перед условным является также действительным, не слишком подробным и более часто используемым. – Fx32

+0

@maksim, почему вы думаете, 'if (! X = anyFunction())' не читается? Ему не нужны никакие комментарии. – JDrake

1

Если вы должны были обратиться к книге Мартина Фаулерса Refactoring improving the design of existing code! Тогда есть несколько случаев, когда это было бы хорошей практикой, например. длинные сложные условные использовать вызов функции или методы, чтобы утверждать свое дело:

"Motivation

One of the most common areas of complexity in a program lies in complex conditional logic. As you write code to test conditions and to do various things depending on various conditions, you quickly end up with a pretty long method. Length of a method is in itself a factor that makes it harder to read, but conditions increase the difficulty. The problem usually lies in the fact that the code, both in the condition checks and in the actions, tells you what happens but can easily obscure why it happens.

As with any large block of code, you can make your intention clearer by decomposing it and replacing chunks of code with a method call named after the intention of that block of code. > With conditions you can receive further benefit by doing this for the conditional part and each of the alternatives. This way you highlight the condition and make it clearly what you > are branching on. You also highlight the reason for the branching."

И да его ответ справедлив и для реализаций Java. Он не присваивает условную функцию переменной, хотя в примерах.

4

Существует один случай, когда вы это делаете, с while -loops.
При чтении файлов, вы делаете обычно работают на жидком так:

void readFile(String pathToFile) { 
    // Create a FileInputStream object 
    FileInputStream fileIn = null; 
    try { 
     // Create the FileInputStream 
     fileIn = new FileInputStream(pathToFile); 
     // Create a variable to store the current line's text in 
     String currentLine; 
     // While the file has lines left, read the next line, 
     // store it in the variable and do whatever is in the loop 
     while((currentLine = in.readLine()) != null) { 
      // Print out the current line in the console 
      // (you can do whatever you want with the line. this is just an example) 
      System.out.println(currentLine); 
     } 
    } catch(IOException e) { 
     // Handle exception 
    } finally { 
     try { 
      // Close the FileInputStream 
      fileIn.close(); 
     } catch(IOException e) { 
      // Handle exception 
     } 
    } 
} 

Посмотрите на while -loop на линии 9. Там, новая строка считывается и сохраняется в переменной, а затем содержание петли побежал. Я знаю, что это не if -statement, но я предполагаю, что цикл while также может быть включен в ваш вопрос.

Причина этого в том, что при использовании FileInputStream, каждый раз, когда вы звоните FileInputStream.readLine(), он читает следующую строку в файле, так что если вы назвали бы его из петли с только fileIn.readLine() != null без присвоения переменной, вместо вызывая (currentLine = fileIn.readLine()) != null, а затем вызывается изнутри цикла, вы получите только каждую вторую строку.

Надеюсь, вы понимаете, и удачи!

0

вы могли бы сделать что-то вроде этого:

if (value = /* sic */ some_function()){ 
    use_value(value) 
} 
Смежные вопросы