I was working on something with node.js, noticed something strange with const keyword. Please refer to the test case script attached with this message.
The logic is straightforward. Make an array of integers from 1 to 100, slice the array every 10 numbers; 1~10 / 11~20 / ..., and print the first number of each subarray; 1, 11, 21, 31, 41, and so on.
The test cases are basically identical to each other with the exception of the sliced subarray is stored. In case 0, you see the subarray is stored as a variable, and the result comes out as expected.
for(var i=0; i<length; i+=step) {
var c = array.slice(i, i+step);
res.push(c[0]);
}
console.log('var ' + res.join(' '));
Result
var 1 11 21 31 41 51 61 71 81 91
However as we move on, strange things start to happen. In case 1, now we store each as a constant, which is block-scoped, and the result is not something you'd expect.
for(var i=0; i<length; i+=step) {
const c = array.slice(i, i+step);
res.push(c[0]);
}
console.log('const ' + res.join(' '));
Result
const 1 1 1 1 1 1 1 1 1 1
Case 2 and 3 are trying to mitigate this behavior. Wrapping the const code line with a function, or even declaring another block-scoped type like let or const before the line does the job.
const.js:37
for(var i=0; i<length; i+=step) {
(function() {
const c = array.slice(i, i+step);
res.push(c[0]);
})();
}
console.log('const in function ' + res.join(' '));
const.js:53
for(var i=0; i<length; i+=step) {
let v;
const c = array.slice(i, i+step);
res.push(c[0]);
}
console.log('let and const ' + res.join(' '));
Result
const in function 1 11 21 31 41 51 61 71 81 91
let and const 1 11 21 31 41 51 61 71 81 91
The behavior was tested on OS X with Google Chrome 44.0.2403.155, Canary 46.0.2481.0, node.js 0.12.7 with harmony flag, io.js 3.0.0. As Apple Safari and Mozilla Firefox work as expected, I believe it's a bug in V8's end.
Don