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

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

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

Из Вы не знаете JS

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

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

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

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


person Gwater17    schedule 16.04.2017    source источник
comment
Автор Википедии может иметь другое представление о scope выражении, чем JavaScript, поскольку эта статья не зависит от языка. Далее в той же статье присвоение переменных в C++ считается побочным эффектом.   -  person le_m    schedule 17.04.2017


Ответы (1)


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

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

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

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

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

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

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

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

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

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

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

a++;

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

b = a++;

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

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

person trincot    schedule 16.04.2017