2016-09-28 25 views
5

我在ES6中实现了一个简单的GCD算法(通过node-esml),并且在更新while循环中的变量值时遇到了(对我来说)奇怪的行为。此代码非常有效:ES6函数中的while循环中的解构赋值不会传播出循环吗?

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)) 

返回预期的答案1。但是,如果我删除临时变量,而使用解构赋值,试图获得相同的结果:

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)) 

它从来没有完成,进一步调试表明,R将始终有一个分配给,x第一个值。看来这两个实现应该是相同的?看到Swapping variables

我也试过用var而不是let无济于事。我是否彻底误解了解构任务或错失了某种微妙的东西?或者它是一个错误?

+1

你的'q'和'temp'变量是[隐含的全局](http://blog.niftysnippets.org/2008/03/horror-of-implicit-globals.html)。使用严格模式! – Bergi

+1

顺便说一句,你为什么不写'函数gcd(r,rdash){'并省略'let [r,rdash] = [x,y]'? – Bergi

回答

7

这不是解构赋值问题,而是ASI(自动分号插入)。这两条线路:

q = Math.floor(rdash/r) 
[r, rdash] = [rdash - q * r, r] 

在实践中是说:

q = Math.floor(rdash/r)[r, rdash] = [rdash - q * r, r] 

这显然不是你的意思。为了解决这个问题,在前面加一个分号[

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))

当然你也可以在以前的行,而不是(q = Math.floor(rdash/r);)末尾添加缺少的分号,但因为你一般不要不使用分号,我假定你正在使用npm coding style

+1

恭喜你找到缺失的分号,但为什么要像在平时一样在第二行的开头添加它,而不是第一行的末尾? – Aaron

+2

@Aaron这是[npm编码风格](https://docs.npmjs.com/misc/coding-style#semicolons)。 –

+0

谢谢,很高兴知道。把分号放在有问题的行的开始处,如果它们通常被忽略,并且问题与前一行聚合在一起,无论它是什么,都是有意义的。 – Aaron