Теоретически, использование оператора пост-инкремента может создать временный. На практике компиляторы JavaScript достаточно умны, чтобы этого избежать, особенно в таком тривиальном случае.
Например, давайте рассмотрим этот пример кода:
sh$ cat test.js
function preInc(){
for(i=0; i < 10; ++i)
console.log(i);
}
function postInc(){
for(i=0; i < 10; i++)
console.log(i);
}
// force lazy compilation
preInc();
postInc();
В этом случае компилятор V8 в NodeJS выдает точно тот же самый байт-код (см., Например, опкоды 39-44 для приращения):
sh$ node --version
v8.9.4
sh$ node --print-bytecode test.js | sed -nEe '/(pre|post)Inc/,/^\[/p'
[generating bytecode for function: preInc]
Parameter count 1
Frame size 24
77 E> 0x1d4ea44cdad6 @ 0 : 91 StackCheck
87 S> 0x1d4ea44cdad7 @ 1 : 02 LdaZero
88 E> 0x1d4ea44cdad8 @ 2 : 0c 00 03 StaGlobalSloppy [0], [3]
94 S> 0x1d4ea44cdadb @ 5 : 0a 00 05 LdaGlobal [0], [5]
0x1d4ea44cdade @ 8 : 1e fa Star r0
0x1d4ea44cdae0 @ 10 : 03 0a LdaSmi [10]
94 E> 0x1d4ea44cdae2 @ 12 : 5b fa 07 TestLessThan r0, [7]
0x1d4ea44cdae5 @ 15 : 86 23 JumpIfFalse [35] (0x1d4ea44cdb08 @ 50)
83 E> 0x1d4ea44cdae7 @ 17 : 91 StackCheck
109 S> 0x1d4ea44cdae8 @ 18 : 0a 01 0d LdaGlobal [1], [13]
0x1d4ea44cdaeb @ 21 : 1e f9 Star r1
117 E> 0x1d4ea44cdaed @ 23 : 20 f9 02 0f LdaNamedProperty r1, [2], [15]
0x1d4ea44cdaf1 @ 27 : 1e fa Star r0
121 E> 0x1d4ea44cdaf3 @ 29 : 0a 00 05 LdaGlobal [0], [5]
0x1d4ea44cdaf6 @ 32 : 1e f8 Star r2
117 E> 0x1d4ea44cdaf8 @ 34 : 4c fa f9 f8 0b CallProperty1 r0, r1, r2, [11]
102 S> 0x1d4ea44cdafd @ 39 : 0a 00 05 LdaGlobal [0], [5]
0x1d4ea44cdb00 @ 42 : 41 0a Inc [10]
102 E> 0x1d4ea44cdb02 @ 44 : 0c 00 08 StaGlobalSloppy [0], [8]
0x1d4ea44cdb05 @ 47 : 77 2a 00 JumpLoop [42], [0] (0x1d4ea44cdadb @ 5)
0x1d4ea44cdb08 @ 50 : 04 LdaUndefined
125 S> 0x1d4ea44cdb09 @ 51 : 95 Return
Constant pool (size = 3)
Handler Table (size = 16)
[generating bytecode for function: get]
[generating bytecode for function: postInc]
Parameter count 1
Frame size 24
144 E> 0x1d4ea44d821e @ 0 : 91 StackCheck
154 S> 0x1d4ea44d821f @ 1 : 02 LdaZero
155 E> 0x1d4ea44d8220 @ 2 : 0c 00 03 StaGlobalSloppy [0], [3]
161 S> 0x1d4ea44d8223 @ 5 : 0a 00 05 LdaGlobal [0], [5]
0x1d4ea44d8226 @ 8 : 1e fa Star r0
0x1d4ea44d8228 @ 10 : 03 0a LdaSmi [10]
161 E> 0x1d4ea44d822a @ 12 : 5b fa 07 TestLessThan r0, [7]
0x1d4ea44d822d @ 15 : 86 23 JumpIfFalse [35] (0x1d4ea44d8250 @ 50)
150 E> 0x1d4ea44d822f @ 17 : 91 StackCheck
176 S> 0x1d4ea44d8230 @ 18 : 0a 01 0d LdaGlobal [1], [13]
0x1d4ea44d8233 @ 21 : 1e f9 Star r1
184 E> 0x1d4ea44d8235 @ 23 : 20 f9 02 0f LdaNamedProperty r1, [2], [15]
0x1d4ea44d8239 @ 27 : 1e fa Star r0
188 E> 0x1d4ea44d823b @ 29 : 0a 00 05 LdaGlobal [0], [5]
0x1d4ea44d823e @ 32 : 1e f8 Star r2
184 E> 0x1d4ea44d8240 @ 34 : 4c fa f9 f8 0b CallProperty1 r0, r1, r2, [11]
168 S> 0x1d4ea44d8245 @ 39 : 0a 00 05 LdaGlobal [0], [5]
0x1d4ea44d8248 @ 42 : 41 0a Inc [10]
168 E> 0x1d4ea44d824a @ 44 : 0c 00 08 StaGlobalSloppy [0], [8]
0x1d4ea44d824d @ 47 : 77 2a 00 JumpLoop [42], [0] (0x1d4ea44d8223 @ 5)
0x1d4ea44d8250 @ 50 : 04 LdaUndefined
192 S> 0x1d4ea44d8251 @ 51 : 95 Return
Constant pool (size = 3)
Handler Table (size = 16)
Конечно, другие компиляторы / интерпретаторы JavaScript могут поступить иначе, но это сомнительно.
В качестве последнего слова, для чего бы это ни стоило, я, тем не менее, считаю, что лучше всего использовать предварительное увеличение, когда это возможно: поскольку я часто переключаю языки, я предпочитаю использовать синтаксис с правильным семантическим для то, что я хочу, вместо того, чтобы полагаться на смекалку компилятора. Например, современные компиляторы Си также не будут иметь никакого значения. Но в C ++ это может оказать значительное влияние с перегруженным operator++
.