全局范围内的前缀或后缀运算符是副作用吗?

Is a prefix or postfix operator in the global scope a side effect?

来自Wikipedia

In computer science, a function or expression is said to have a side effect if it modifies some state outside its scope or has an observable interaction with its calling functions or the outside world.

来自You Don't Know JS

There are other side-effecting expressions, though. For example:

var a = 42;
var b = a++;

我知道 42 被分配给 b,然后 a 变成 43。但是,由于 a 和 b 都在全局范围内,为什么这会被视为副作用?

如有任何帮助,我将不胜感激。

在最严格的定义中,对变量的每次赋值都是副作用,因为它符合维基百科文章中给出的这个例子:

For example, a particular function might [...] modify one of its arguments

因此 a++ 也是如此:它可能不是 JavaScript 术语中的函数,但运算符只是一种不同的语法,通常可以称为函数。

然而,在 实际 术语的使用中,当操作是 "bad" 副作用时,即说​​当操作有副作用时函数还有另一种效果,考虑到它出现的上下文,它被认为是 main 效果。

例如,假设您有一个修改其参数的函数,return是一个值。例如 Array.prototype.push。如果调用此函数并忽略其 return 值,那么我们 实际上 不会说有副作用,即使严格来说有:

a = [];
a.push('x');

在最严格的意义上,即使是 a = []; 中的赋值运算符也意味着副作用(因为 a 被修改了),但在普通话中我们不会考虑一个(坏的)副作用。

但是,当您使用 a.push('x') 的 return 值时,则有两个作用发挥作用:returned 值和 a 的修改。在这种情况下,上下文会使 return 值成为 main 效果,而 a 的突变是副作用:

a = [];
if (a.push('x') == 1) {
    console.log('you have one element in your array');
}

这里我们当然有一个副作用,无论是在严格意义上还是在术语的普通意义上。上下文现在是一个求值表达式,因此 push 的 return 值在这里起主要作用。 a 的突变成为副作用。

同样的情况也发生在你的例子中。如果 a++; 作为语句出现,即未使用 returned 值,那么我们通常不会称其为(坏的)副作用:

a++;

然而,当也使用 return 值时,我们确实说它有副作用:

b = a++;

同样,这是根据该术语在口语中的实际用法;在严格意义上,a++ 总是代表副作用。

关于 SO 的更多阅读: