<p>在JavaScript和Python中,<code>/=</code>是一个“增强赋值”操作符,其含义几乎相同。在</p>
<p>在JS中:</p>
<pre><code>var i = 10;
i /= 2;
</code></pre>
<p>…相当于:</p>
^{pr2}$
<p>在Python中:</p>
<pre><code>i = 10
i /= 2
</code></pre>
<p>……同样相当于(不完全相同,但对于数字来说足够接近):</p>
<pre><code>i = 10
i = i / 2
</code></pre>
<p>然而,有一个非常大的区别。在</p>
<p>在JavaScript中,赋值是一个表达式,它有一个值,这个值就是被赋值给变量的值。所以:</p>
<pre><code>var i = 10;
var j = i /= 2;
</code></pre>
<p>…大致相当于:</p>
<pre><code>var i = 10;
i /= 2;
var j = i;
</code></pre>
<p>在Python中,赋值是一个语句。它没有值,不能在表达式中使用。所以:</p>
<pre><code>i = 10
j = i /= 2
</code></pre>
<p>…引发一个<code>SyntaxError</code>。在</p>
<hr/>
<p>移植在表达式中间使用赋值(增强或其他方式)的代码通常需要将表达式分解成多行和/或找到重写表达式的方法,使其不需要任何赋值。(但通常情况下,这并不是坏事,因为最初的表达式无论如何都不太可读……)</p>
<p>例如,假设JS从左到右计算操作数(我不确定这是肯定的?)公司名称:</p>
<pre><code>def easeInQuad(x, t, b, c, d):
t /= d
return c*t*t+b
</code></pre>
<p>一般来说,您可以这样做:</p>
<pre><code>old_t = t
t /= d
</code></pre>
<p>然后用<code>t/=d</code>替换之前<code>t</code>的任何实例,并将<code>t/=d</code>中的所有实例保留为单独的。幸运的是,我们不需要以前的东西。在</p>
<p>如果你仔细想想,你可以很容易地得到同样的效果,而不需要改变<code>t</code>,在一行中,更容易阅读,通过以下任何一种方式:</p>
<pre><code>return c * (t/d) * (t/d) + b
return c * (t/d)**2 + b
return c * t*t / d*d + b
</code></pre>
<p>用C语言思考的人会立刻抱怨这些都“太慢了”。毕竟,第一个做了一个额外的除法,第二个做了求幂而不是乘法,第三个做了两个乘法而不是一个。恐怖!在</p>
<p>当然,您可以始终使用临时变量:</p>
<pre><code>t_over_d = t/d
return c * t_over_d * t_over_d + b
</code></pre>
<p>…但是,对于一个C程序员来说,这意味着您正在使用一个有价值的寄存器。当然,在1985年之后编写的每一个编译器都会在<code>t_over_d</code>出现时检测到{<cd3>}是死的,并重用同一个寄存器,但是如果可以的话,为什么不强制它重用寄存器,特别是如果它还保存了一些击键操作呢?在</p>
<p>在JS或Python中,乘法的开销只是调用函数和解释字节码等开销的一小部分,以至于您根本不会注意到。同时,重新绑定一个局部变量(尤其是在V8风格或PyPy风格的JIT解释器中)的成本可能比传递一个未命名的临时结果的成本高得多。在</p>
<p>因此,这是一个错误的“优化”范例,它使代码更难理解,同时可能会使代码变慢而不是加速,而且在一个无论如何都不可能成为值得优化的瓶颈的领域。在</p>
<hr/>
<p>因为gnibbler提出了JavaScript是否真的能保证这个求值顺序的问题</p>
<p>首先,JavaScript被定义为“Firefox做什么”(和“Spidermonkey做什么”),但这应该是同一件事,如果不是,那么JavaScript可以做两件事,所以这是两倍的好,对吗。但是ECMAScript<em>是由标准定义的,每个JS实现(不管名字是什么)都只是口头上说说而已,我们可以假设ECMAScript 5.1是所有实现都遵循的标准(只要“所有实现”都意味着“Opera”),这是真的。你可以找到它<a href="http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262%20edition%205.1,%20June%202011.pdf" rel="nofollow">here</a>。在</p>
<p>因此,在es5.1中:<strong>11.5乘法运算符</strong>保证<code>(t/=d)</code>的结果将在<code>t</code>之前被计算,<strong>11.13.2复合赋值</strong>保证了对<code>t/=d</code>的求值将在完成之前设置{<cd3>}的值。(你必须仔细阅读“evaluate”是什么意思,什么是<code>GetValue</code>和<code>SetValue</code>意思是说,但我很肯定这是有保证的。)</p>