2016-09-28 18 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