这是什么JS语法?表达式中的赋值?(x != null && (y = x))

6

我正在使用这个JS插件,但遇到了一些我从未见过的语法。我知道它在做什么,但不确定它为什么有效。

下面是一个实例:

settings.maxId != null && (params.max_id = settings.maxId);

这只是利用条件语句和单个=吗?这是JS常见的语法吗?

嘿,这似乎是糟糕的代码 - (!=) 表示不等于,并检查对象是否不为空,而第二个条件 (=) 表示赋值 - 我想知道为什么在这种情况下它被用于条件语句。干杯! - Tats_innit
@Tats_innit: 条件语句在哪里?这段代码完全有效,只是有点愚蠢。 - Lightness Races in Orbit
@LightnessRacesinOrbit 嗨,抱歉我假设了条件语句,因为它使用了非空检查,如果我错了,请原谅。- 啊,很酷,所以这不仅是我的问题,实际上这是一个糟糕的语句!谢谢。 - Tats_innit
我记得在 ANSI C 中,读取文件时这种编码风格很流行:while (nextChar = file.readLine()),但我认为自那以后就再也没有见过了,因为它是一个极差的反模式。 - jbabey
3个回答

15
JavaScript中的=运算符是一个表达式,它会评估分配的值。由于它是一个表达式,因此它可以在允许表达式的任何地方使用,即使它会导致副作用。 因此:
settings.maxId != null && (params.max_id = settings.maxId)

意思是:如果settings.maxId不为null,则(只有这种情况,因为&&短路)计算右表达式(params.max_id = settings.maxId),这将导致settings.maxId的值被分配给params.max_id。 这样写更加清晰易懂:
if (settings.maxId != null) {
  params.max_id = settings.maxId
}

愉快的编程。


3
< p > && 运算符被称为“布尔AND”运算符。通常,您会在if语句中看到它:

if (x == true && y == false) {

但这并不是一种限制。您可以在任何有效的表达式中使用它,将其操作数的布尔值“组合”成单个布尔结果,根据逻辑“AND”操作:

var z = (x == true && y == false);
// z is now true or false, accordingly
&& 的一个优点是它可以进行“短路”。在表达式 false && true 中,由于第一个操作数为 false,整个表达式只能求值为 false,因此第二个操作数甚至都不会被求值。
让我们再来检查一下:
var z = (false && foo());
// z is now false

在这个语句中,函数foo甚至没有被调用!它不需要被调用,程序就知道z将会是false。这不仅仅是一种优化——你可以依靠它。一些愚蠢的人使用这种技术重写条件语句:
if (x == 0) {
   foo();
}

将难以阅读的单个表达式转换成易于阅读的形式:

(x == 0) && foo();

现在,考虑分配可以像函数调用一样是一个表达式:

var a = (b = c);

或者:

var a = (b = foo());

通过上述技术添加条件语句:
var a = ((x == 0) && (b = foo()));

如果 x 不等于 0,那么整个表达式 b = foo() 就不会被求值,因为发生了短路。

我们甚至不需要对 && 操作的结果进行任何操作,如果我们不将它存储到 a 中,你只需要这样写:

(x == 0) && (b = foo());

这是一条语句,只有在x等于0时才会将b赋值为foo()的返回值。请避免使用此语句,因为它很难阅读,可以使用if语句代替。

3
这个语句只有在settings.maxId != null时才会赋值给params.max_id = settings.maxId,因为&&是一种短路逻辑运算符。
这种行为是由于JavaScript将条件评估到必要的程度。因此,如果第一个条件为假且第二个条件是AND,则没有必要进一步检查。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接