How to pass a function that's a property of another object into a function and call it in javascript?

Multi tool use
Multi tool use


How to pass a function that's a property of another object into a function and call it in javascript?



If I have an object in Javascript and one of its properties is a function:


function cow() {

this.timesMooed = 0;

this.sayMoo = function () {
this.timesMooed++;
return "moo";
};
}



Say I also have another function that takes some function as an argument, calls it and records the result:


var actionResults = ;
function doAction(action) {
actionResults.push(action());
}



Now let's put this into practice and see what happens:


var jerry = new cow();
doAction(jerry.sayMoo);
console.log(actionResults);
// Outputs ["moo"] -this is correct
console.log(jerry.timesMooed);
// Outputs 0 -uh oh



How can I pass in the function so that it's Jerry that is running the function?


Jerry





doAction(jerry.sayMoo.bind(jerry));
– ASDFGerte
Jul 2 at 2:25


doAction(jerry.sayMoo.bind(jerry));





This question has been asked and answered dozens, if not hundreds, of times on SO. Search and research harder.
– torazaburo
Jul 2 at 3:19




4 Answers
4



When you pass the reference to the function doAction and then call it with action(), the calling context changes and this is what determines the value of this. You need to use bind to keep the value of this locked to jerry :


doAction


action()


this


bind


this


jerry




function cow() {
this.timesMooed = 0;
this.sayMoo = function () {
this.timesMooed++;
return "moo";
}
}

var actionResults = ;
function doAction(action) {
actionResults.push(action());
}

var jerry = new cow();
// use bind, which makes a function with `this` set properly
doAction(jerry.sayMoo.bind(jerry));

console.log(actionResults);
console.log(jerry.timesMooed);



Alternatively you can use arrow functions => which bind this lexically:


=>


this




function cow() {
this.timesMooed = 0;
// use arrow function here instead
this.sayMoo = () => {
this.timesMooed++;
return "moo";
}
}

var actionResults = ;
function doAction(action) {
actionResults.push(action());
}

var jerry = new cow();
// no need to bind() now
doAction(jerry.sayMoo);

console.log(actionResults);
console.log(jerry.timesMooed);





Brilliant answer!
– fuzz
Jul 2 at 2:49





This is exactly the depth that I wanted; thankyou so much for a clear and thorough answer!
– PolymorphismPrince
Jul 2 at 4:45



Problem is that this keyword is used in a method and we call that method from a receiver object and this is not bound to the object that we expect it to be bound to i.e. jerry in this case.


this


this



Note that this value in methods and functions must be set explicitly when we need a specific object bound to the function’s this value.


this


this



Solution



Solution is simple to use correct context



i.e. we want this to refer to jerry hence while invoking doAction method with sayMoo method of jerry object use bind function call and pass jerry as this argument


this


doAction(jerry.sayMoo.bind(jerry));



try creating a constructor




class cow {
constructor(){
this.timesMooed = '';
}
sayMoo() {
this.timesMooed+=1;
return "moo";
}
}

var actionResults = ;
function doAction(action) {
actionResults.push(action);
}

var jerry = new cow();
doAction(jerry.sayMoo());
console.log(actionResults);
console.log(jerry.timesMooed);





This is good, except for the fact that (1) it's unnecessary and (2) it address the OP's issue--he want's to push the function call itself, to be executed later (with the right this), not the result of the function call.
– torazaburo
Jul 3 at 2:49


this



As @Mark_M says the better way is to use arrow function but this feature force you to use ES6 instead of ES5 because bound function introduce in ES5.
Another way is to use benefits of variable scope like this:


function cow() {
this.timesMooed = 0;
var that = this;
this.sayMoo = function (){
that.timesMooed++;
return "moo";
}
}

...






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

TMJnL xleu,uHa,ml7zFs49Y z5uSMd5bz,N3 y Jl,6VxJ2Tnjq6a
Sp7DRdr7L DuexaC qGy7ku 1LRCEfGZto1 g Lm,ga,130KmTgkJr5OID0A up

Popular posts from this blog

Rothschild family

Boo (programming language)