2016-04-28 119 views
0

要學習javascript,我使用它來實現和測試經典算法。javascript + mocha:可能是在for循環中聲明的函數的關閉問題

這是我在執行二進制搜索和試驗它的嘗試:

var assert = require('assert') 

function binsearch (xs, v) { 
    if (xs === undefined || xs.length === 0) { return null } 

    var lo = 0 
    var hi = xs.length - 1 

    while (lo <= hi) { 
    var i = (lo + hi)/2 | 0 

    if (xs[i] === v) { 
     return i 
    } else if (v < xs[i]) { 
     hi = i - 1 
    } else if (v > xs[i]) { 
     lo = i + 1 
    } 
    } 

    return null 
} 

var check_bsearch = function (bsearch, xs, x, i) { 
    it(bsearch.name + ' [' + xs + '] ' + x + ' ' + i, function() { 
    assert.equal(bsearch(xs, x), i) 
    }) 
} 

describe('Test binsearch', function() { 
    describe('on a sorted array', function() { 
    var xs = [] 

    for (var i = 0; i < 2; ++i) { 
     xs[i] = 2 * i 

     for (var j = 0; j <= i; ++j) { 
     check_bsearch(binsearch, xs, 2 * j, j) 
     check_bsearch(binsearch, xs, 2 * j + 1, null) 

     check_bsearch(binsearch, xs, -1, null) 
     check_bsearch(binsearch, xs, -2, null) 

     check_bsearch(binsearch, xs, 2 * i + 1, null) 
     check_bsearch(binsearch, xs, 2 * i + 2, null) 
     } 
    } 
    }) 
}) 

爲了再現什麼,我要說的話,複製上面的代碼到一些bsearch.js文件,用類似sudo npm install -g mocha安裝mocha.js並最終運行文件:mocha bsearch.js

一個測試應該失敗:xs = [0], x = 2和預期的結果null。如果您單獨重新創建此測試,它將會通過。

我懷疑這是一個關閉問題。您可能已經注意到我已經在使用幫助功能check_bsearch來獲得預期的關閉環境。但是,我顯然缺少一些東西。我如何修復測試?

回答

1

數組通過引用傳遞。會發生什麼是當你循環修改你傳遞給你的函數的xs數組,並且到測試實際運行時,它們都會得到相同的值。您應該複製數組,以便每個測試在調用它時獲取其值的快照。它可以如此簡單:

var check_bsearch = function (bsearch, xs, x, i) { 
    xs = xs.slice(); // Make a private copy of xs.