js中运算符副作用总结与例子
js中赋值运算符,递增递减运算符,delete运算符具有副作用,简单地说就是前后表达式的值会相互影响,除此之外其它的js运算符都没有副作用。
但函数表达式和对象创建表达式有些特别,在函数体或者构造函数内部使用了这些运算符产生了副作用的时候,我们说函数调用表达式和构造函数是有副作用的。
一个例子:
c = (a++) + a;
这条语句中含有三个子表达式,我们用三个符号来表示,即
exp1 | c |
---|---|
exp2 | a++ |
exp3 | a |
我们知道在js总是严格按照从左到右的顺序计算子表达式,即先计算exp1再计算exp2,再计算exp3.
计算子表达式的结果如下
exp1 | undefined |
---|---|
exp2 | 1 (因为a++是先是先使用后自加,故exp2=1,然后a加1变为2,此时a指向的内存空间的内容变为2,也就是a变为了2,下一个表达式的a为2) |
exp3 | 2 |
然后再根据js运算规则,最终计算出c=1+2=3
另外一个例子:
一般来说,a += b;和a = a + b;是等价的,但是当a包含副作用表达式的时候,两者就不等价了
例如:
i = 1;
var data = [0,1,2];
data[i++] += 2;
执行一次计算结果:
data[0] | 0 |
---|---|
data[1] | 3 |
data[2] | 2 |
i = 1;
var data = [0,1,2];
data[i++] = data[i++] 2;
执行一次计算结果:
data[0] | 0 |
---|---|
data[1] | 4 |
data[2] | 2 |
原因就在于第二个程序中有三个子表达式,第二个 data[i++]
实际上式 data[2]
,故data[1]=data[2]+2=4
。