如何比较 javascript 中的 2 个函数?我不是在谈论内部参考。说
var a = function(){return 1;};
var b = function(){return 1;};
可以比较a
和b
吗?
如何比较 javascript 中的 2 个函数?我不是在谈论内部参考。说
var a = function(){return 1;};
var b = function(){return 1;};
可以比较a
和b
吗?
var a = b = function( c ){ return c; };
//here, you can use a === b because they're pointing to the same memory and they're the same type
var a = function( c ){ return c; },
b = function( c ){ return c; };
//here you can use that byte-saver Andy E used (which is implicitly converting the function to it's body's text as a String),
''+a == ''+b.
//this is the gist of what is happening behind the scences:
a.toString( ) == b.toString( )
闭包意味着当你说“比较”时你需要非常小心你的意思。例如:
function closure( v ) { return function(){return v} };
a = closure('a'); b = closure('b');
[a(), b()]; // ["a", "b"]
// Now, are a and b the same function?
// In one sense they're the same:
a.toString() === b.toString(); // true
// In another sense they're different:
a() === b(); // false
能够到达函数之外,意味着在一般意义上,比较函数是不可能的。
但是,在实际意义上,您可以使用 Esprima 或 Acorn 等 Javascript 解析库获得很大的帮助。这些让你建立一个“抽象语法树”(AST),它是你的程序的 JSON 描述。例如,你的return 1
函数的 ast看起来像这样
ast = acorn.parse('return 1', {allowReturnOutsideFunction:true});
console.log( JSON.stringify(ast), null, 2)
{
"body": [
{
"argument": {
"value": 1, // <- the 1 in 'return 1'
"raw": "1",
"type": "Literal"
},
"type": "ReturnStatement" // <- the 'return' in 'return 1'
}
],
"type": "Program"
}
// Elided for clarity - you don't care about source positions
AST 包含进行比较所需的所有信息——它是数据形式的 Javascript 函数。您可以根据需要标准化变量名称、检查闭包、忽略日期等。
有很多工具和库可以帮助简化流程,但即便如此,这可能需要大量工作,而且可能不切实际,但大多数情况下是可能的。
您可以比较可能包含函数引用的两个变量,以查看它们是否引用了完全相同的函数,但您无法真正比较两个单独的函数以查看它们是否执行相同的操作。
例如,您可以这样做:
function foo() {
return 1;
}
var a = foo;
var b = foo;
a == b; // true
但是,你不能可靠地做到这一点:
function foo1() {
return 1;
}
function foo2() {
return 1;
}
var a = foo1;
var b = foo2;
a == b; // false
你可以在这里看到第二个:http : //jsfiddle.net/jfriend00/SdKsu/
在某些情况下,您可以.toString()
在函数上使用运算符,但这是将函数的文字字符串转换与另一个进行比较,即使有一点点与实际产生的结果无关紧要,也不会起作用。我想不出在任何情况下我会推荐它作为一种可靠的比较机制。如果你认真考虑这样做,我会问为什么?您真正想要完成什么并尝试找到解决问题的更强大的方法。
函数上的 toString() 返回准确的声明。你可以修改jfriend00的代码来测试一下。
这意味着您可以测试您的函数是否完全相同,包括您在其中放置了哪些空格和换行符。
但首先你必须消除它们名称上的差异。
function foo1() {
return 1;
}
function foo2() {
return 1;
}
//Get a string of the function declaration exactly as it was written.
var a = foo1.toString();
var b = foo2.toString();
//Cut out everything before the curly brace.
a = a.substring(a.indexOf("{"));
b = b.substring(b.indexOf("{"));
//a and b are now this string:
//"{
// return 1;
//}"
alert(a == b); //true.
正如其他人所说,这是不可靠的,因为单个差异空白会使比较错误。
但是,如果您将其用作保护措施呢?(“自从我创建函数以来,有人更改过我的函数吗?”)那时您可能真的希望进行这种严格的比较。
使用模板文字的ES6+ 清洁解决方案:
const fn1 = () => {}
const fn2 = () => {}
console.log(`${fn1}` === `${fn2}`) // true
基本上是指:
console.log(fn1.toString() === fn2.toString()) // true