2

While comparing functions in Javascript, am thinking that it compares the memory at which function is defined to cross-check that the given 2 functions are equal.
So, was trying to compare a member function by accessing it from 2 different instances of same object as below:

function testFn(name) {
    var name = name;
    var self = this;
    self.compareFn = function() {
        console.info(name);
    }    
}

var fn1 = new testFn('fn1');
var fn2 = new testFn('fn2');
console.info(fn1.compareFn == fn2.compareFn);  //Returns false

Have defined an object testFn with one member function ("compareFn") and created 2 instances of it (fn1,fn2) and but on comparing "fn1.compareFn == fn2.compareFn",it fails.

Remember, that member function is shared across multiple instances and only local variables will be allocated separately.
Please suggest why this comparison fails.

6 Answers 6

1

This fails because each time you do new testFn it is generating a new compareFn; you're not pointing to a reference outside of the constructor or inheriting from a prototype.

You can't access a variable from inside a Constructor with a shared function, because it doesn't have access to that closure. If you want to achieve a shared function you will need to move these values into a reference-able space too, i.e.

function testFn(name) {
    var vars = {}; // using object because javascript passes refs for objects
    this.vars = vars; // make `this.vars` point to `vars`
    vars.name = name; // set whatever on your object
}
testFn.prototype.compareFn = function () {
    console.info(this.vars.name); // can access `vars` through ref of `this.vars`
};

Now

var a = new testFn('foo'), b = new testFn('bar');
a.compareFn === b.compareFn; // true;
a.compareFn(); // logs "foo"
Sign up to request clarification or add additional context in comments.

Comments

1

That method is actually created for each instance. You want to declare it on the object's prototype. See below.

var testFn = function(name) {
    this.name = name;
}

testFn.prototype.compareFn = function() {
   console.info(this.name);
}

var fn1 = new testFn('fn1');
var fn2 = new testFn('fn2');
console.info(fn1.compareFn == fn2.compareFn);  //Returns true

1 Comment

I think you beat me by a few seconds :)
1

If you want the function to be shared across multiple instances, do it like this:

function testFn(name) {
    var self = this;
}

testFn.prototype.compareFn = function() {
  console.log(name);
};    

var fn1 = new testFn('fn1');
var fn2 = new testFn('fn2');
console.log(fn1.compareFn == fn2.compareFn); 

DEMO

Comments

1

I think the reason it comes out as false is because, here at least, instead of testing for equality of the outcome of the 'source code' it is testing for the location of memory they both refer to. The reason for this is because it can't test for equality in any other way.

Different ways to measure equality:

  • Testing for the return value would be done by running the function:

    fn1.compareFn() == fn2.compareFn() //true

  • Testing for the source would be done by calling toString() (note: this is not standardised among browsers!):

    fn1.compareFn.toString() == fn2.compareFn.toString() //true

However, as they are different instances (you are not calling testFn == testFn or fn1.compareFn == fn1.compareFn), they refer to different memory locations so the test for equality comes out as false.

More info about that can be found on this question too: 'how compare two static function are equal or not in javascript'.

Also as a note, you should be using a triple equals (===) rather than a 'double equals' as the latter does not test for equality of type (i.e. checking that 2 variables are both numbers, as well as having the value 5).

2 Comments

the only creative answer! gratz!
@rafaelcastrocouto Thanks, I got a bit too into it ;)
0

Every time you call the function testFn, it creates a new variable and assigns a function to it...

So yes, they are identical functions, but they are not the same thing.

There are a couple of other patterns you could use to get the results you'd like. In this case, you'd want to use the prototypical pattern:

// Constructors should start with an upper case letter
function TestFn(name) {
  this.name = name;
}

TestFn.prototype.testFn = function() {
  console.info(this.name);
}    


var fn1 = new TestFn('fn1');
var fn2 = new TestFn('fn2');
console.info(fn1.compareFn == fn2.compareFn);  // Returns true

Comments

0
function testFn(name) {
    this.name = name;
}

testFn.prototype.compareFn = function() {
    console.info(name);
}

var fn1 = new testFn('fn1');
var fn2 = new testFn('fn2');
console.info(fn1.compareFn == fn2.compareFn);  //Returns TRUE

You are redefining the function each time the constructor is called, therefore the methods are not equal. By assigning them to the prototype, it is the same method.

If you're interested in keeping name (or other variables or functions private), then check out this SO answer.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.