JavaScript中++和+=1之间的区别

32

有人能解释一下为什么下面的函数会给出不同的结果吗?第一个似乎不起作用,但第二个却可以。我感到困惑,因为我以为+=1和++是一样的。

(我并不打算真正使用这段代码,这只是为了演示差异。)

/*function 1*/
function incrementIfZero1(base,element) {

    if (element == 0) {
        return base++;
    }
    else
    {
        return base;
    }
};


/*function 2*/
function incrementIfZero2(base,element) {

    if (element == 0) {
        return base+=1;
    }
    else
    {
        return base;
    }
};

incrementIfZero1(1,0) /* -> 1*/
incrementIfZero2(1,0) /* -> 2*/
任何帮助都非常感激。
谢谢,
Robin
[编辑:]
感谢您的回复,现在我明白了。我之前还尝试了以下语句,结果与函数1相同:
return (base++)

我现在很惊讶,这个表达式没有和第2个函数给出相同的结果——我本来以为括号会强制先计算再返回。你有任何想法为什么会发生这种情况吗?


感谢您的快速回复 - 请查看底部的编辑以获取另一个相关问题。 - RobinL
8个回答

32

当你使用return base++时,它返回的是在递增之前的base值。为了确保先执行递增操作再返回值,应该使用++base

否则+++=1相同。

[编辑] 针对您的编辑,我尝试将随机语句放在括号中,大多数数学运算符按预期响应,但该递增操作似乎例外,可能是因为前缀递增和后缀递增的语法高度故意,这个语句本身返回一个特定的值,无论您是否将其包装在括号中。


3
谢谢 - 我想我懂了。因此,return (x++)和return x++是相同的,因为两者都没有对x进行赋值,所以它们都表示:“返回x并增加1”。而return x+=1表示“将x+1赋值给x,并返回x的结果值”。 - RobinL
2
@RobinL 表达式 x++ 返回 x(到 return 语句,将其从函数返回到外部),然后将其递增。表达式 x+=1 递增 x,然后返回它。 - bfavaretto
尽管这可能是显而易见的,但为了后代的缘故,请不要在生产环境中使用 return x++ 或类似的代码,除非清楚说明副作用的时间! - Chris Collett

7

return (base++)

我很惊讶这段代码没有和第二个函数返回相同的结果。我本以为圆括号会强制先进行表达式求值再返回结果,你知道为什么不是这样吗?

无论有没有圆括号,自增操作都会被执行。问题在于,在 JavaScript 中,任何表达式都会产生一个值并返回该值。例如,当你执行 var x = 2 + 2 时,2 + 2 被求值,然后将其“返回”给赋值运算符 =,最后将该值分配给变量 x。后缀 ++ 运算符(如 base++)的行为不同:它确实会对前面的变量执行自增操作,但表达式返回的是加 1 前的值。而前缀 ++ 运算符则可以按照你的意愿工作,++base 返回加 1 后的值。


我知道这与其他答案大多数重复,但我希望它能帮助您理解它的行为方式。 - bfavaretto
谢谢您的回答 - 它确实为为什么return x++和return (x++)之间没有区别提供了有用的额外信息。 - RobinL

6
return base++;

这是后置自增运算符。它会将base所持有的值加1,然后返回递增前的原始值。

return base += 1;

将原始值加1,然后返回该值。这是一种前缀递增运算符。也可以写成:

return ++base;

你确定 "base += 1;" 是前增量而不是后增量吗? - Dany Caissy

5

您返回了base++。这是后缀递增,因此递增是在返回之后处理的。对于这种特定情况,return ++base;将是正确的。


@JustinNiessner 实际上不是这样的。对于大多数(所有?)具有后缀表示法的语言来说都是如此。 - Luke
@Luke - https://dev59.com/B3RB5IYBdhLWcg3wV196 (Java)和https://dev59.com/PHE95IYBdhLWcg3wRL0t (C++)会有不同的看法。我实际上也是这么想的,直到我尝试为我不经常使用的语言进行双重检查。 - Justin Niessner
@JustinNiessner PHP也是这样工作的。也许“大多数”不是正确的词。使用“一些”可能更合适。 - Luke

4

警告!如果用+++=变异两种不同类型的字符串和数字,将会产生差异:

count是一个字符串时,count += 1似乎进行了类型转换并将第二个数字转换为字符串,而count++将参数字符串count转换为数字,并将其加1。

let count = process.argv[2]

while (count < 5) {
  console.log('Inside of the loop. Count is', count)
  count += 1 // NOT likely what you want! Now, try it with count++
}

console.log('Outside of loop. Count is', count)

另一个例子:

> let num = '2'
undefined
> num++
2
> num
3

// VS using +=

> let num2 = '2'
undefined
> num2 += 1
'21'
> num2
'21'

2

为了澄清一下。

"variable += 1" 的等价于 "variable = variable + 1"。它不等同于 variable++!

像 variable++ 这样的表达式可以直接使用,而前者是赋值操作。


2
在第一个函数中发生的是: return base++; // 首先返回base的值,然后对其进行递增。
在第二个函数中: return base+=1; // 这里先递增变量,然后再将其返回。
使用简写赋值运算符具有更高的优先级,即它会在同一行内完成其工作。

0

注意:

x = 1; y = (x++ * 10 + 1);

等同于:

y = 1 * 10 + 1 = 11

实际上:

x = 1; y = (++x * 10 + 1);

等同于:

y = 2 * 10 + 1 = 21;

最后:

++x ;

或者

x++ ;

没有区别!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接