Reputation: 11372
What I want to do is retrofit a serialisation method to an existing JavaScript type, which is a member of an inheritance tree. It is very nearly working, but my function is operating on the parent type rather than the type I am trying to associate it with. So to take a very basic example:
function Animal( species, population )
{
this.species = species;
this.population = population;
}
Animal.prototype.getDetail = function()
{
return "Species: "+this.species+" Population: "+this.population;
}
function Mammal( species, population, bodyTemperature )
{
Animal.apply(this, [species, population]);
this.bodyTemperature = bodyTemperature;
}
Mammal.prototype= new Animal();
Mammal.constructor = Mammal;
var Serialise= {
init: function() {
Mammal.prototype.serialise = this.serialiseMammal.bind(Mammal.prototype);
},
serialiseMammal: function() {
return {
species: this.species,
population: this.population,
bodyTemperature: this.bodyTemperature
};
}
}
Serialise.init();
var bob = new Mammal("Human", 7000000000, 36.6);
console.log( bob.serialise() );
What is happening is that the serialise
function is running in the context of the Animal
type which is correct because that is the prototype of Mammal
, but if I try to bind it directly to the Mammal
, nothing happens at all. Once again, I find myself out of my depth in JavaScript's scope.
The reason I am doing this is to keep all my serialisation/deserialisation in one place, so that it's there if I need it, but I don't always have to have it included- I guess in another language it might be behaving slightly like a mixin.
What do I need to do to ensure that the any call of serialise()
on an instance of the Mammal
type will correctly apply the Serialise.serialiseMammal()
function in the context of the current instance? Is there a way of doing this without binding the functions to individual instances when they are created?
I'm also trying to improve my own expertise with the language and doing things in more of a JavaScript way, so if the whole approach is totally wack or against the grain of the language, that would be good to know.
Upvotes: 0
Views: 63
Reputation: 14581
I do not fully understand why you want to decorate it this way, as opposed to just putting the specialized serialiseMammal
directly on the Mammal.prototype
, as below:
Mammal.prototype.s2 = function() {
return {
species: this.species,
population: this.population,
bodyTemperature: this.bodyTemperature
};
};
I called this s2
so as not to conflict. This is the identical code from serialiseMammal
. However, if you prefer the decorator-style pattern you have used, then you just need to do:
var Serialise= {
init: function() {
Mammal.prototype.serialise = this.serialiseMammal;
},
serialiseMammal: function() {
return {
species: this.species,
population: this.population,
bodyTemperature: this.bodyTemperature
};
}
}
Within the context of init
, then this
refers to Serialise
, so this.serialiseMammal
is the function you have. But it is just a function, nothing more. When you next call bob.serialise()
, the function is called in the context of the moment. This, this
inside of bob.serialise()
, which is the code from serialiseMammal
, is set to bob
.
Here is a fiddle with it. http://jsfiddle.net/6un6qho1/1/
Upvotes: 1