Friday, September 6, 2013

Javascript closure anomoly

Javascript closure anomoly

The output from this script is:
[ [ 1, 2, 3, 4 ], 10 ]
[ [ 91, 92, 93, 94 ], 10 ]
[ [ 8888, 8888, 8888, 8888 ], 10 ]
[ [ 'one', 'two', 'three', 'four' ], 10 ]
But if I un-comment hogs = [2, 4, 6, 8], the output is:
[ [ 1, 2, 3, 4 ], 10 ]
[ [ 1, 2, 3, 4 ], 10 ]
[ [ 1, 2, 3, 4 ], 10 ]
[ [ 1, 2, 3, 4 ], 10 ]
If I leave it commented out but un-comment hogs = [333, 444, 555, 666],
the output is:
[ [ 1, 2, 3, 4 ], 10 ]
[ [ 91, 92, 93, 94 ], 10 ]
[ [ 8888, 8888, 8888, 8888 ], 10 ]
[ [ 8888, 8888, 8888, 8888 ], 10 ]
I would like to understand simple javascript closures well enough to
predict their behavior. Is that possible short of analysing the specs for
the engine? I would also like to know why re-defining an entire array in
one statement has such drastically different side effects from
re-assigning the array's individual values one at a time. I am afraid to
get very creative because I don't know how to predict side effects, and I
can't find a clue in the literature.
var x = 10;
var hogs = [1, 2, 3, 4];
var array5 = (function () {
var ar = [];
var z = x;
var w = hogs;
function g() {
ar.push(w);
ar.push(z);
return ar;
} return g;
})()();
console.log(array5);
// hogs = [2, 4, 6, 8]; Un-commenting this prevents array5 from changing.
x = 40;
hogs[0] = 91;
hogs[1] = 92;
hogs[2] = 93;
hogs[3] = 94;
console.log(array5);
hogs[0] = 8888;
hogs[1] = 8888;
hogs[2] = 8888;
hogs[3] = 8888;
console.log(array5);
// hogs = [333, 444, 555, 666]; // Un-commenting this prevents //further
change.
hogs[0] = 'one';
hogs[1] = 'two';
hogs[2] = 'three';
hogs[3] = 'four';
x = 40;
console.log(array5);

No comments:

Post a Comment