1

I'm stuck with this problem. Need to check if the 2 functions are the same or refer to the same. So the scenario is kind of like this : fn1 function are anonymous.

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

here both this.fn1 and this.json1.fn1 points to the same function definition. Is there a way to find out if they are pointing the same or not ?

I have tried using function.toString() but this gives the same output for any function i.e;

function() { [native code] }

and on this being compared it gives true as the output for any 2 function that are not even same.

On comparing === It's not considering them as same. On debugging it shows that it is pointing to the function at the same line.

On doing Object.is(this.fn1,this.json1.fn1); is returning false , which means they are not the same object.

How these functions are set to the attribute are through using the bind function such as :

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

So now we know these are 2 different Objects

Pratik
  • 11
  • 4
  • guessing https://stackoverflow.com/questions/9817629/how-do-i-compare-2-functions-in-javascript does not help out – epascarello Apr 05 '18 at 03:03
  • Do you want to compare the entire function (including its name) or just the body of the function? Or, are you talking about comparing anonymous functions? – Scott Marcus Apr 05 '18 at 03:05
  • 1
    Just use `===` to see if two variables referencing a function (or an object) refer to the same place in memory – CertainPerformance Apr 05 '18 at 03:10
  • @epascarello : It doesn't help out as I pointed out function {[native code]}; is what I get when I convert it to string – Pratik Apr 05 '18 at 05:22
  • @CertainPerformance : Doesn't work even if they point to the same location then go to the else case . I guess it's because the objects that store the reference are different objects. – Pratik Apr 05 '18 at 05:23
  • @ScottMarcus : comparing anonymous functions – Pratik Apr 05 '18 at 05:24
  • @Pratik If they point to the same place in memory, then they are the same object / function; if they don't point to the same place in memory, then they're different objects / functions, there's no other possibility. – CertainPerformance Apr 05 '18 at 05:26

2 Answers2

1

Functions are objects in JavaScript. Even two functions that are written exactly the same are still two distinct objects in memory and will never be equal.

All you can do is convert the functions to strings and compare the strings. I would guess though that you didn't actually invoke the .toString() function during your comparison expression and instead compared the actual .toString function code.

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); }
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
  • These functions are anonymous functions so when you do toString here you get the whole source code and you can compare but when I do it all I get as an output for toString() is -> "function () {[native code]};" – Pratik Apr 05 '18 at 05:27
  • @Pratik It doesn't matter whether you have anonymous functions or not. What you are seeing is the result of retrieving the code stored in the `toString` property (<-- notice there are no parenthesis after it?) as opposed to *invoking* it with parenthesis as in `toString()`, you won't get that. I'll update my answer to illustrate. – Scott Marcus Apr 05 '18 at 12:40
0

Consider the example below:

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();
  • fun3 is a copy of fun1, it returns false in comparision.
  • fun2 and fun1 are the reference to the same function.
  • Inside, test() function, assign fun1 to a new function. However, fun2 is still pointing to the old function, so it returns false when comparing them.

So, it is safe to compare 2 references of functions using ===.

FisNaN
  • 2,517
  • 2
  • 24
  • 39
  • I'm getting the function assigned to properties of 'this' scope. On debugging I see they point to the same point in the code. But on comparing them with === it fails. It's like 'this' will be like : fnName : f() attribute : {fnName:f()} where both f() point to the same line – Pratik Apr 05 '18 at 05:44