2014-11-05 1 views
4

ECMAScript 언어 사양 specifies은 곱셈 연산자가 교환 가능 (A * B == B * A)이라는 것을 나타냅니다. 그러나 A 나 B에 대입 연산자가 포함 된 경우에는 유지되지 않습니다. 예를 들어 나는 브라우저의 콘솔에 다음을 입력하면 : 곱셈은 교환 가능하지 않습니까?

var x = 1; 
(x + 2) * ((x = 4) + 1); 

15을 준다, 그러나 :

var x = 1; 
((x = 4) + 1) * (x + 2) 

가 30

을 제공 또는 교환 법칙이 성립이 모든 변수는 일단 교환 법칙이 성립 의미 않습니다 그들의 가치관으로 해결 되었습니까? 그러나이 스펙은 수학적 곱셈 연산이 아니라 "* 연산자"에 대해 말합니다.

+0

흥미 부는 '(X = 4)'에 정상적인 동작이다 표현'((x = 4) +1)'은'3 * 5' 초가됩니다 ond'5 * 6' – Satpal

+0

"Commutative"는 평가 된 표현식의 값을 분명히 나타냅니다. '*'연산자가 피연산자의 평가 순서에 관심을 갖도록 정의 할 수 없습니다. 피연산자의 평가 순서가 매우 깊기 때문입니다 (예 :'foo() * bar()). – deceze

+0

왜 관심 있어요? 예, 곱셈은 commmutative입니다. 그러나이 경우 할당의 효과로 인해 두 경우에 서로 다른 값을 사용합니다. 따라서'(1 + 2) * (4 + 1)'이'(4 + 1) * (4 + 2) '와 같지 않다는 것은 비 commutativity의 증거라고 여겨집니다. 어쨌든 계산 중간에 이러한 과제를 수행하는 것이 최선의 방법은 아닙니다. 나는 스펙이 무엇을 말하고 있는지 확신하지 못한다. 그러나 특정 엔진이 양면을 역순으로 또는 심지어 평행으로 평가할 가능성이있다. –

답변

3

두 번째 예제의 x + 2는 3 대신 6입니다. 이미 x = 4로 지정 했으므로;

의미 후 :

((x = 4) + 1) 

무슨 일

(x + 2) == (4 + 2) == 6 

(4+1) * 6 = 30 

+1

나는 이것이 정상적인 동작이며, 왜 그런 일이 일어 났으며, 스펙의 정의에 대해서는 확실하지 않다는 것을 알고 있습니다. –

+0

'*'행동의 정의는 '5 * 6'상황에 이르렀을 때만 관련이 있습니다. 그전에'*'는 전혀 관련이 없습니다. 어떤 종류의 AST 관점에서가 아니라 통용 될 때 통용 적이 지요. 그건별로 의미가 없습니다. 그렇다면 어떤 함수 나 연산자도 교환 가능하지 않습니다. – clacke