在条件陈述中分配变量,良好实践与否?

时间:2010-04-05 01:49:05

标签: javascript

一年前,我将经典的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;
}

基本上我发现我可以在if条件语句中为一个值赋值,并立即检查赋值,就好像它是布尔值一样。

为了更安全的赌注,我通常将其分为两行代码,首先分配然后检查变量,但现在我发现了这一点,我只是想知道在经验丰富的JavaScript开发人员看来它是否是好的做法?

11 个答案:

答案 0 :(得分:103)

我不推荐它。问题是,您尝试比较值时看起来像是一个常见错误,但使用单个=代替=====。例如,当你看到这个:

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

你不知道他们是打算做什么,还是打算写这个:

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

如果您真的想要进行任务,我建议您进行明确的比较:

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

答案 1 :(得分:19)

我认为没有证据证明这不是好习惯。是的,它可能看起来像是一个错误,但这很容易通过明智的评论来弥补。举个例子:

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

为什么允许该功能第二次运行:

alert(processorIntensiveFunction());

因为第一个版本LOOKS不好?我不能同意这个逻辑。

答案 2 :(得分:12)

我做了很多次。为了绕过JavaScript警告,我添加了两个parens:

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

你应该避免它,如果你真的想使用它,在它上面写一条评论,说明你在做什么。

答案 3 :(得分:5)

您也可以在Java中执行此操作。不,这不是一个好习惯。 :)

(并使用Javascript中的===进行类型化的相等。阅读Crockford的关于JS的The Good Parts一书。)

答案 4 :(得分:4)

有一种情况,当您使用while - 循环时 阅读文件时,您通常会这样做:

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
        }
    }
}

查看第9行的while - 循环。在那里,读取一个新行并将其存储在变量中,然后运行循环的内容。我知道这不是if - 声明,但我想你的问题也可以包含一段时间。

这样做的原因是当使用FileInputStream时,每次调用FileInputStream.readLine()时,它都会读取文件中的下一行,所以如果您只是通过{来自循环调用它{1}}没有分配变量,而不是调用fileIn.readLine() != null,然后从循环内部调用它,你只会得到每一行。

希望你明白,祝你好运!

答案 5 :(得分:3)

您也可以在Java中的if语句中进行分配。一个很好的例子就是阅读并写出来:

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();
}

答案 6 :(得分:1)

这不是好习惯。你很快就会对此感到困惑。它看起来与常见错误类似:误用“=”和“==”运算符。

你应该把它分成2行代码。它不仅有助于使代码更清晰,而且在将来也很容易重构。想象一下,你改变IF条件?您可能会意外删除该行,并且您的变量不再获取分配给它的值。

答案 7 :(得分:1)

如果您要参考Martin Fowlers的书Refactoring improving the design of existing code !然后有几种情况,这将是良好的做法,例如。使用函数或方法调用断言你的案例的长复杂条件:

  

“动机

     

程序中最常见的复杂领域之一在于复杂的条件逻辑。   当你编写代码来测试条件并根据各种各样的事情做各种事情   条件,你很快就会得到一个很长的方法。方法的长度本身就是使其难以阅读的因素,但条件增加了难度。问题   通常在于条件检查和操作中的代码,   告诉你会发生什么,但很容易模糊它为什么会发生。

     

与任何大块代码一样,您可以通过分解它来使您的意图更清晰   使用以该代码块的意图命名的方法调用替换代码块。 &GT;对于条件部分,您可以通过条件获得进一步的好处   每个替代方案。通过这种方式,您可以突出显示条件,并清楚地了解您的情况&gt;正在分支。您还要强调分支的原因。“

是的,他的回答对Java实现也有效。虽然在示例中没有将条件函数赋值给变量。

答案 8 :(得分:0)

我认为这更像是一种古老的C风格;它在JavaScript中不是很好的练习,所以你应该避免它。

答案 9 :(得分:0)

你可以这样做:

if (value = /* sic */ some_function()){
  use_value(value)
}

答案 10 :(得分:0)

我是从golang来到这里的,通常会看到类似的东西

if (err := doSomething(); err != nil) {
    return nil, err
}

其中err仅限于该if块。因此,这就是我在es6中所做的事情,这看起来很丑陋,但并没有使我相当严格的eslint规则产生问题,并且实现了同样的目的。

{
  const err = doSomething()
  if (err != null) {
    return (null, err)
  }
}

多余的花括号定义了一个新的“词汇范围”吗?这意味着我可以使用const,而err对于外部块不可用。