【问题标题】:How to inspect a JavaScript Bound Function如何检查 JavaScript 绑定函数
【发布时间】:2016-07-20 10:19:09
【问题描述】:

有什么方法可以检查 JavaScript 绑定函数吗?

我想从一个函数返回一个绑定函数,并在单元测试中断言绑定函数的目标、boundThis 和 boundArgs。它们似乎在 ECMAScript 中被定义为内部对象,无法在程序中访问。

有什么方法可以访问它们吗?或者可能有类似需求的人已经写了一些模块补丁 Function.prototype.bind()?

【问题讨论】:

  • FWIW... 在单元测试中,您通常希望测试一段代码的作用,而不是如何。 “什么”是测试,“如何”是执行。这似乎是在单元测试中关注的错误。
  • stackoverflow.com/questions/26545549/…。调用绑定函数时使用的this 不是函数上的某种隐藏属性。它是用于包装原始函数以创建绑定函数的逻辑的一部分。你不能检查它,就像你不能检查函数中的局部变量或函数内部的任何其他逻辑一样,正如@Bergi 正确指出的那样,你不想也不应该这样做。

标签: javascript


【解决方案1】:

不,没有(除非您启动调试器)。

无论如何,您都不应该测试绑定函数。您也可以使用闭包实现完全相同的行为,这也不会暴露封闭变量。没关系。您不应该测试实现,而是测试行为 - 所以只需检查调用返回的函数是否确实调用了具有预期值的目标。

【讨论】:

  • 但我绝对不同意你不应该测试绑定函数。如今,ES6 Promise 被频繁使用。许多函数返回承诺。但是promise是一个不透明的对象,没有办法检查promise是什么,也没有办法通过值进行相等性检查。一个更好的方法是返回一个绑定函数,如果它可以被检查的话。这比解决承诺和断言结果要好得多,因为承诺可能有副作用。保持测试函数“纯”是解决问题的关键。
  • Promise 类似于 Haskell 中的 monad,因为它包含一个值。但它本身并不是一个值。这是个问题。并且函数返回它不能是纯的。一种解决方法是使用表示绑定函数的对象作为返回值而不是 promise。它可以毫无歧义地转换为一个承诺。那么这个对象可以直接被断言,而不是解析promise。函数返回这样的对象可以是纯的。
  • 此外,假设这样的适配器函数被命名为 M()。它接受一个表示绑定函数的对象并返回一个 Promise,然后在 Promise/then/catch 链中。所有纯函数都被 M 函数包裹,然后传递给 then 或 catch。这种方法的另一个好处是,如果你想测试代码覆盖率,你不需要在 Promise 中模拟任何副作用函数,你需要做的就是改变 M 函数的行为,检查输入和输出测试数据为结果。我不能说 Promise 不好,但它只是向函数式编程迈进了一半。
  • 是的,承诺类型是Monad。但这并不能使它不纯,甚至不能保证副作用。是的,您不能在其上定义 Eq(忽略对象身份),但实际上,您也不能在函数上执行相同的操作。与 Promise 具有 1:1 对应关系的“绑定函数”(无论是什么)在所有用途上都等于 Promise。
  • 听起来您正在寻找一种 IO monad 实现,它不仅包含异步(如 Promise 那样)而且还包含副作用。当然有库,但实际上你的一元函数组合只会保持函数组合,产生不透明的函数对象。测试函数是否相等的唯一方法是运行它们。从 PromiseIO monad 的唯一变化是您可以包含(和模拟)副作用。
猜你喜欢
  • 2021-05-08
  • 2011-06-18
  • 1970-01-01
  • 2015-09-25
  • 2012-04-21
  • 1970-01-01
  • 1970-01-01
  • 2012-12-26
相关资源
最近更新 更多