如何在Javascript中测试函数的相等性

Jam*_*ron 22 javascript equality function

如何才能对bar和foo的平等进行积极的测试?

 foo = function() {
    a = 1;
 }; 

 bar = function() {
    a = 1;
 }; 

 if (foo === bar) alert('baz');
 if (foo == bar) alert('qux');
Run Code Online (Sandbox Code Playgroud)

以上条件都是错误的.

更新 - 根据要求我需要测试功能相等性的原因

我正在构建一个发布/订阅框架,需要传递回调以取消订阅主题.

请看小提琴:http://jsfiddle.net/jamiefearon/hecMS/47/

Ale*_*pin 26

您可以通过比较调用它们的结果来检查两个函数的内容是否完全相同toString

 var foo = function() {
    a = 1;
 }; 

 var bar = function() {
    a = 1;
 }; 

alert(foo.toString() == bar.toString());?
Run Code Online (Sandbox Code Playgroud)

但是,如果只有一个不同的角色,那将会失败.另一方面,检查两个函数是否同样的事情几乎是不可能的.

  • 但这也完全没用. (29认同)
  • 绝对不!这对于像lodash debounce这样的功能至关重要. (6认同)
  • 请注意,这可能会返回误报 - 如果您的函数引用其包含范围内定义的任何变量,它们可能具有完全相同的源代码,但行为不同。有关示例,请参阅[此答案](/sf/answers/2244328411/)。 (2认同)

pol*_*.ph 20

问题在于功能上存在不同的平等概念.

  • 参考平等.函数存储在内存中的某个地方,并从某个地址开始.对于两个函数名(基本上是内部地址),引用相等性给出trueiff两个名称指向同一地址.当你指定一个时,这是一个问题bar = foo.JavaScript中使用引用相等性.
  • 另一个答案中提出的源代码平等.如果更改函数体中的任何字符,它将无法工作.此外,toSource目前(截至2014年)仅在Firefox中可用,因为它不是W3C标准化的.
  • 源代码的句法等式.可以使用抽象语法树来抵制空格和注释中的修改.可以使用lambda演算中定义的alpha等价(即函数的等价,其中变量一致地重命名),但也有
  • 扩展相等,当函数相同时,如果它们以相同的方式工作.有一个定理说明没有算法来检查函数的扩展相等性,所以它肯定不是你要搜索的那个.虽然,在一些比JS更高级的语言中有
  • 整体相等(你要么证明函数是相等的,要么你的程序不能编译)和
  • 观察平等(这一点太先进了,无法解释).

所以,照顾你认为平等的东西.

  • 如果你可以为每一个添加一个例子,那么这将是一个很好的答案! (4认同)

Poi*_*nty 3

您可以测试两个变量是否引用完全相同的函数对象,并且可以将函数转换为字符串并查看它们是否真的完全相同,但是尝试确定两个函数是否执行完全相同的操作会有点困难更难,或者可能更难。

通过缩小器运行一对函数会很有趣,因为缩小器会进行大量的静态分析。

  • @Pointy我认为这是不正确的。如果您有两个字符相同的函数,那么它们的操作仍然可能不同,因为它们可能引用静态闭包中的变量。例如, function() { return x } 将根据 x 在定义函数的范围内的内容而不同地返回。 (5认同)
  • 不是一点点困难,而是实际上不可能。 (4认同)
  • 好吧,两个函数是否等价的问题与数学有关,而不是与编程有关,但您可能对http://stackoverflow.com/questions/1132051/is-finding-the-equivalence-of-two-functions-undecidable感兴趣 (4认同)
  • @duri 好吧,我在这里了解到,粗鲁地说某件事是“不可能的”是一种羞辱的好方法:-) 不过,总的来说,我同意你的观点,因为像 JavaScript 这样的动态语言的完整静态分析不是可能的。 (3认同)