Deltax76
Deltax76

Reputation: 14263

Inheritance with Knockout.js

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

Answers (4)

pashaplus
pashaplus

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

Karthik Renkarajan
Karthik Renkarajan

Reputation: 29

You could try using the underscore.js extend functionality to do the inheritance.

Upvotes: 0

Elias Van Ootegem
Elias Van Ootegem

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

John Moses
John Moses

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

Related Questions