【问题标题】:Javascript comparing if 2 functions are exact sameJavascript比较两个函数是否完全相同
【发布时间】:2018-04-05 03:00:47
【问题描述】:

我被这个问题困住了。需要检查这2个功能是否相同或引用相同。 所以场景是这样的: fn1 函数是匿名的。

function fnName(args) {
if(this.fn1 === this.json1.fn1)
//this is true
else
//this is false
}

这里 this.fn1 和 this.json1.fn1 都指向同一个函数定义。有没有办法找出它们是否指向相同?

我尝试过使用 function.toString() 但这对任何函数都给出了相同的输出,即;

function() { [native code] }

在此进行比较时,它给出了任何 2 个甚至不相同的函数的输出结果。

比较 === 并没有将它们视为相同。调试时显示它指向同一行的函数。

在做 Object.is(this.fn1,this.json1.fn1); 时返回 false ,这意味着它们不是同一个对象。

如何将这些函数设置为属性是通过使用绑定函数,例如:

fn1 = fn1.bind(this);
json1["fn1"] = fn1.bind(this)

所以现在我们知道这是 2 个不同的对象

【问题讨论】:

  • 你想比较整个函数(包括它的名字)还是只比较函数体?或者,您是在谈论比较匿名函数吗?
  • 只需使用=== 即可查看引用函数(或对象)的两个变量是否引用了内存中的同一位置
  • @epascarello :正如我指出的函数 {[native code]}; 并没有帮助。是我将其转换为字符串时得到的
  • @CertainPerformance :即使它们指向相同的位置然后转到 else case 也不起作用。我猜是因为存储引用的对象是不同的对象。

标签: javascript function compare this


【解决方案1】:

函数是 JavaScript 中的对象。即使两个写得完全相同的函数在内存中仍然是两个不同的对象,永远不会相等。

您所能做的就是将函数转换为字符串并比较字符串。我猜你在比较表达式期间实际上并没有调用.toString() 函数,而是比较了实际的.toString 函数代码。

var o1 = {
  foo: function (message){
    console.log(message);
  }
};

var o2 = {
  log: function (message){
    console.log(message);
  }
};

var o3 = {
  log: function (msg){
    console.log(msg);
  }
};

var test = o1.foo;


function compare(f1, f2){
  // You must convert the functions to strings and compare those:
  console.log(f1.toString() === f2.toString());
}

compare(o1.foo, o2.log);  // true - the two functions are identical
compare(o1.foo, o3.log);  // false - the two functions are not identical
compare(o1.foo, test);    // true - the two variables reference the same one function

// This is just to show how not properly calling toString() affects the results:
console.log(o1.foo.toString);   // function toString() { [native code] }
console.log(o1.foo.toString()); // function (message){ console.log(message); }

【讨论】:

  • 这些函数是匿名函数,所以当你在这里执行 toString 时,你会得到整个源代码,你可以进行比较,但是当我这样做时,我得到的 toString() 的输出是 -> "function ( ) {[本机代码]};"
  • @Pratik 是否有匿名函数并不重要。您看到的是检索存储在 toString 属性中的代码的结果(toString() 那样用括号调用 ,你不会明白的。我会更新我的答案来说明。
【解决方案2】:

考虑下面的例子:

var fun1 = function() { console.log('fun1') };
var fun2 = fun1;
var fun3 = fun1.bind({});

console.log(fun1 === fun2); // true
console.log(fun1 === fun3); // false

function test() {
  fun1 = () => { console.log('new function') }
  fun1();
  fun2();
  fun3();
  console.log(fun1 === fun2); // false
}

fun1();
fun2();
fun3();
test();
  • fun3fun1 的副本,它返回 false 进行比较。
  • fun2fun1 是对同一个函数的引用。
  • test() 函数内部,将fun1 分配给一个新函数。但是,fun2 仍然指向旧函数,因此在比较它们时返回 false。

因此,使用=== 比较两个函数引用是安全的。

【讨论】:

  • 我正在获取分配给“this”范围属性的函数。在调试时,我看到它们指向代码中的同一点。但是在将它们与 === 进行比较时,它失败了。就像'this'会像:fnName:f()属性:{fnName:f()}其中两个f()都指向同一行
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多