Reputation: 14263
I have some code like this:
var A = function(a,b,c) {
var self = this;
self.a = ko.observable(a);
...
self.function1 = ko.computed(function () {
dothing(a);
...
}
self.function2 = ko.computed(function () {
dothing(b);
...
}
}
var B = function(a,b,c,d) {
var self = this;
self.a = ko.observable(a);
...
self.function1 = ko.computed(function () {
dothing(a);
...
}
self.function2 = ko.computed(function () {
dothing(b);
...
}
}
How can I "extract" function1 and function2 to a function that A and B can share?
Upvotes: 2
Views: 1176
Reputation: 3706
var AB=function(){
self=this;
self.function1=function(){
//----something------
}
self.function1=function(){
//----something------
}
}
var A=function(){
var self=this;
AB.apply(self,arguments);
}
var B=function(){
var self=this;
AB.apply(self,arguments);
}
Upvotes: 0
Reputation: 29
You could try using the underscore.js extend functionality to do the inheritance.
Upvotes: 0
Reputation: 76395
That's just where prototypes fit in:
function AB()
{};//empty object
AB.prototype.function1 = function()
{
var self = this;//doesn't have access to self, but `this` will point to either A or B
//do stuff
};
var A = function()
{
var self = this;//constructor
}
var B = function()
{
var self = this;//constructor
}
A.prototype = new AB;
A.prototype.constructor = A;
B.prototype = new AB;
B.prototype.constructor = B;
//marginally shorter:
A.prototype = B.prototype = new AB;
A.prototype.constructor = A;
B.prototype.constructor = B;
//instances:
var foo = new A();
var bar = new B();
console.log(foo.function1 === bar.function1);//logs true
Having said that, personally, I prefer to define my constructors regularly:
function A()
{
var self = this;
}
foo = new A();
console.log(Object.getPrototypeOf(foo).constructor.name);//logs A
Whereas your code assigns an anonymous function to a variable, which means that the constructor doesn't have a name:
foo = new A();
console.log(Object.getPrototypeOf(foo).constructor.name);//logs ''
It's not that big of a deal, but just so you know...
Reference a method from the global (or any other) scope:
var virtualNewFunction = new A();//create object
virtualNewFunction = virtualNewFunction.function1;//virtualNewFunction now references function1
virtualNewFunction();
The closure will be accessible (exposed), still, but be very careful with this
:
A = function()
{
var self = this;
this.function1 = function()
{
console.log(this);
console.log(self);
};
}
foo = new A();
foo.function1();//logs A twice
foo = foo.function1
foo();//logs this -> window! self => A
An other possibility is "borrowing" a function:
A = function()
{
var self = this;
this.function1 = function()
{
console.log(this);
console.log(self);
};
}
B = function()
{//no method
var self = this;
}
foo = new A();
bar = new B();
foo.function1.apply(bar,[]);//call as though function1 was method of B
Again, be careful: in this case this
logs B
, but self
still references A
! You could build in certain "safety nets":
this.function1 = function()
{
self = this !== window && this !== self ? this : self;//redefine self to current caller object, unless it's window
console.log(this);
console.log(self);
};
But honestly, you might do well reading up on the this operator to grasp all this referencing trickery. It's not that hard once you get the basics. Also check the call and apply methods for more details on how to "share/borrow" methods
Upvotes: 5
Reputation: 1283
You could change the scope of the function by pulling it out of that object.
var function1 = function() {
}
var function2 = function() {
}
var A = function(a,b,c) {
var self = this;
self.a = ko.observable(a);
...
self.function1 = ko.computed(function1)
self.function2 = ko.computed(function2)
}
Upvotes: 0