Является ли префикс или постфиксный оператор в глобальной области видимости побочным эффектом?

Из Википедии:

В информатике функция или выражение, как говорят, имеют побочный эффект, если они изменяют какое-то состояние за пределами своей области или имеют наблюдаемое взаимодействие с их вызывающими функциями или внешним миром.

От тебя не знают JS

Однако есть и другие побочные эффекты. Например:

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

Я понимаю, что 42 присваивается b, а затем a становится 43. Однако, поскольку a и b находятся в глобальной области видимости, почему это считается побочным эффектом?

Буду признателен за любую помощь.

1 ответ

Решение

В самом строгом определении каждое присвоение переменной является побочным эффектом, так как он соответствует этому примеру, приведенному в статье Википедии:

Например, конкретная функция может [...] изменить один из своих аргументов

Так что это также верно для a++: это может быть не функция в терминологии JavaScript, но операторы - это просто другой синтаксис для того, что в целом можно назвать функцией.

Однако при практическом использовании этого термина говорят, что операция имеет побочный эффект, когда она является "плохим" побочным эффектом, то есть когда эта функция также имеет другой эффект, который считается основным, учитывая контекст в котором это происходит.

Например, допустим, у вас есть функция, которая изменяет свой аргумент и возвращает значение. Например Array.prototype.push, Если эта функция вызывается и ее возвращаемое значение игнорируется, то на практике мы бы не сказали, что был побочный эффект, даже если строго говоря:

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

В самом строгом смысле даже оператор присваивания в a = []; будет означать побочный эффект (так как а является измененным), но в обычной речи мы не будем считать, что (плохой) побочный эффект тоже.

Однако, когда вы используете возвращаемое значение a.push('x'), тогда два эффекта играют роль: возвращаемое значение и модификация a. В этом случае контекст сделает это возвращаемое значение основным эффектом, а мутацию - побочным эффектом:

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

Здесь у нас, безусловно, есть побочный эффект, как в строгом, так и в общепринятом смысле этого слова. Контекст теперь является оцененным выражением, и поэтому возвращаемое значение push играет главную роль здесь. Мутация становится побочным эффектом.

То же самое происходит в вашем примере. Если a++; происходит как оператор, то есть возвращаемое значение не используется, тогда мы обычно не будем называть это (плохим) побочным эффектом:

a++;

Однако, когда также используется возвращаемое значение, мы говорим, что оно имеет побочный эффект:

b = a++;

Опять же, это соответствует практическому использованию термина в разговорной речи; в строгом смысле, a++ всегда представляет собой побочный эффект.

Еще немного чтения по SO:

Другие вопросы по тегам