Reputation: 169
I was implementing a simple GCD algorithm in ES6 (through node-esml) and came upon (to me) strange behaviour with updating values of variables inside a while loop. This code works fantastically:
function gcdWithTemp(x, y) {
let [r, rdash] = [x, y]
while (r != 0) {
q = Math.floor(rdash / r)
temp = r
r = rdash - q * r
rdash = temp
}
return(rdash)
}
console.log(gcdWithTemp(97, 34))
Returning the expected answer of 1
. However, if I remove the temporary variable and instead use destructuring assignment to try and achieve the same results:
function gcdWithDestructuredAssignment(x, y) {
let [r, rdash] = [x, y]
while (r != 0) {
q = Math.floor(rdash / r)
[r, rdash] = [rdash - q * r, r]
}
return(rdash)
}
console.log(gcdWithDestructuredAssignment(97, 34))
It never completes, further debugging shows that r will always have the first value assigned to, x
. It seems that these two implementations should be identical? see Swapping variables
I've also tried with using var
instead of let
to no avail. Am I drastically misunderstanding the point of destructuring assignment or missing something subtle? Or is it a bug?
Upvotes: 6
Views: 454
Reputation: 92471
That's a problem not with destructuring assignment, but with ASI (automatic semicolon insertion). These two lines:
q = Math.floor(rdash / r)
[r, rdash] = [rdash - q * r, r]
in practice mean this:
q = Math.floor(rdash / r)[r, rdash] = [rdash - q * r, r]
which obviously is not what you meant. To fix that, add a semicolon in front of [
:
function gcdWithDestructuredAssignment(x, y) {
let [r, rdash] = [x, y]
while (r != 0) {
q = Math.floor(rdash / r)
;[r, rdash] = [rdash - q * r, r]
}
return(rdash)
}
console.log(gcdWithDestructuredAssignment(97, 34))
Of course you can add the missing semicolon at the end of the previous line instead (q = Math.floor(rdash / r);
), but since you generally don't use semicolons, I assumed that you're using npm coding style.
Upvotes: 8