Javascript, add function to prototype
In javascript, can you add functions to a prototype with something like curry?
I am trying with this code
var helloGoodBye = function (name, fun) {
return function(message) {
console.log('hello : ' + name);
console.log(message);
console.log('byebye : ' + name);
return fun(message)
}
}
var Machine = function (){
this.state = 'green';
};
Machine.prototype = {
green: helloGoodBye('green', function (message){
this.state = 'red';
}),
red: helloGoodBye('red', function (message){
this.state = 'green';
})
}
var sm = new Machine();
sm[sm.state]('first message');
sm[sm.state]('second message');
and i am getting this output
"hello state: green"
"first message"
"byebye state: green"
"hello state: green"
"second message"
"byebye state: green"
but this method does not work, perhaps because the this.state
called in functions is this.state
living in the global scope.
source to share
Yes, you just need to force the method to call a callback on fun
the receiver object. Use call
:
function helloGoodBye(name, fun) {
return function(message) {
console.log('hello : ' + name);
console.log(message);
console.log('byebye : ' + name);
return fun.call(this, message);
// ^^^^^ ^^^^
}
}
source to share
This is because the this
inside is func
not an instance of your class. It is a global object window
. The anonymous function returned helloGoodBye
is one that has its own this
set for an instance of the class (this is a function attached to the prototype). func
is an anonymous function, locked in a closure, but it has nothing to do with an instance of the class itself.
Use an alternative, for example Function.prototype.call
, to explicitly state this
:
var helloGoodBye = function (name, fun) {
return function(message) {
console.log('hello : ' + name);
console.log(message);
console.log('byebye : ' + name);
return fun.call(this, message); // use the this in this scope which will be the instance of the object
}
}
var Machine = function (){
this.state = 'green';
};
Machine.prototype = {
green: helloGoodBye('green', function(message) {
this.state = 'red';
}),
red: helloGoodBye('red', function(message) {
this.state = 'green';
})
}
var sm = new Machine();
console.log(sm);
sm[sm.state]('first message');
sm[sm.state]('second message');
source to share