Search code examples
javascriptdefinitionside-effectspostfix-operator

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


From 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.

From You Don't Know JS

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

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

I get that 42 is assigned to b and then a becomes 43. However, since a and b are both in the global scope why would this be considered a side effect?

I'd appreciate any help.


Solution

  • In the most strict definition, every assignment to a variable is a side-effect as it fits with this example given in the Wikipedia article:

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

    So this is also true for a++: it may not be a function in the JavaScript terminology, but operators are just a different syntax for what in general could be called a function.

    However, in practical use of the term, an operation is said to have a side-effect when it is a "bad" side-effect, i.e. when that function also has another effect, one that is considered the main effect, given the context in which it occurs.

    For instance, let's say you have a function that modifies its argument and returns a value. For example Array.prototype.push. If this function is called and its return value is ignored, then we would in practice not say there was a side effect, even though strictly speaking there is:

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

    In the most strict sense even the assignment operator in a = []; would imply a side-effect (since a is modified), but in common speech we would not consider that a (bad) side-effect either.

    However, when you use the return value of a.push('x'), then two effects play a role: the returned value, and the modification of a. In that case, the context would make that return value the main effect, and the mutation of a the side-effect:

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

    Here we certainly have a side-effect, both in the strict and common meaning of the term. The context now is an evaluated expression, and so the return value of push plays the main role here. The mutation of a becomes the side-effect.

    The same happens in your example. If a++; occurs as a statement, i.e. the returned value is not used, then we would not commonly call it a (bad) side-effect:

    a++;
    

    However, when also the return value is used, we do say it has a side-effect:

    b = a++;
    

    Again, this is according to the practical use of the term in colloquial speech; in the strict sense, a++ always represents a side effect.

    Some more reading on SO: