javascript + mocha:可能是for循环中声明的函数的闭包问题

时间:2016-04-28 10:14:30

标签: javascript node.js mocha

为了学习javascript,我用它来实现和测试经典算法。

这是我尝试实现二进制搜索和测试:

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文件中,使用类似mocha.js的内容安装sudo npm install -g mocha,然后运行文件:{{1 }}

一个测试应该失败:mocha bsearch.js和预期结果为xs = [0], x = 2的测试。如果你单独重新创建这个测试,它将通过。

我怀疑这是一个关闭问题。您可能已经注意到我已经使用辅助函数null来获得预期的闭包环境。但是,我显然遗漏了一些东西。我该如何修复测试?

1 个答案:

答案 0 :(得分:1)

通过引用传递数组。当您循环时,您将修改传递给函数的xs数组,并且在测试实际运行时,它们都会获得相同的值。您应该复制数组,以便每个测试在调用时获取其值的快照。它可以很简单:

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