在 if 条件语句中赋值变量,这是否是一种好的做法?

一年前,我从经典的面向对象语言(如 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));
}
return false;
}

基本上,我刚刚发现我可以在 if 条件语句中将一个变量赋给一个值,然后立即检查赋值,就像它是布尔值一样。

为了安全起见,我通常将它分成两行代码,先赋值,然后检查变量,但是现在我发现了这一点,我只是想知道在有经验的 JavaScript 开发人员眼中这是否是一个好的实践?

240300 次浏览

你也可以在 Java 中这样做。不,这不是一个好的做法。 :)

(使用 Javascript 中的 ===实现类型相等。阅读克罗克福德关于 JS 的《好的部分》一书。)

为了绕过 JavaScript 警告,我添加了两个括号:

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

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

我不建议这么做。问题是,这看起来像一个常见的错误,您尝试比较值,但使用一个单一的 =而不是 =====。例如,当你看到这个:

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

你不知道这是他们的本意,还是他们的本意:

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

如果你真的想在适当的地方做作业,我建议你也做一个明确的比较:

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

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

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

您也可以在 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();
}

我没有看到任何证据表明这不是好的做法。是的,它可能看起来像一个错误,但是通过明智的评论很容易纠正。举个例子:

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

为什么要允许该函数第二次运行:

alert(processorIntensiveFunction());

因为第一个版本看起来很糟糕? 我不同意这种逻辑。

如果你要参考马丁福勒斯的书 重构改进现有代码的设计!然后有几种情况下,这将是一个很好的实践,例如,使用函数或方法调用来断言你的情况的复杂条件:

动机

程序中最常见的复杂性之一在于复杂的条件逻辑。 当您编写代码来测试条件并根据不同的 条件下,您很快就会得到一个相当长的方法。方法的长度本身就是一个难以阅读的因素,但是条件增加了阅读的难度。问题是 通常在于这样一个事实,即代码在条件检查和操作中, 告诉你发生了什么,但很容易掩盖为什么会发生。

对于任何大的代码块,您可以通过分解它和 用根据代码块的意图命名的方法调用替换代码块。 > 在有条件的情况下,您可以通过对有条件的部分和 每一个选择。通过这种方式,您可以突出显示条件,并使其清楚地显示您 > 正在分支的内容。你还强调了分支的原因。”

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

有一种情况下,当你这样做,与 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语句,但我想 while 循环也可以包含在您的问题中。

这样做的原因是,当使用 FileInputStream时,每次调用 FileInputStream.readLine()时,它都会读取文件中的下一行,所以如果只用 fileIn.readLine() != null从循环中调用它,而没有赋值变量,而不是调用 (currentLine = fileIn.readLine()) != null,然后再从循环内部调用它,那么只能得到每两行。

希望你能理解,祝你好运!

你可以这样做:

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

我从戈兰来到这里,在这里经常可以看到

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

其中 err的作用域仅限于该 if块。因此,下面是我在 es6中所做的,它看起来相当丑陋,但是并没有让我相当严格的 eslint 规则发牢骚,并且达到了同样的效果。

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

额外的大括号定义了一个新的“词法范围”?这意味着我可以使用 const,而 err不能用于外部块。